7 ポインタ (P.61) ポインタを使うと, メモリ上のデータを直接操作することができる. 例えばデータの変更 やコピーなどが簡単にできる. また処理が高速になる. 7.1 ポインタの概念 変数を次のように宣言すると, int num; メモリにその領域が確保される. 仮にその開始のアドレスを 1

Similar documents
(2) 構造体変数の宣言 文法は次のとおり. struct 構造体タグ名構造体変数名 ; (1) と (2) は同時に行える. struct 構造体タグ名 { データ型変数 1; データ型変数 2;... 構造体変数名 ; 例 : struct STUDENT{ stdata; int id; do

Microsoft Word - 3new.doc

4 分岐処理と繰返し処理 ( 教科書 P.32) プログラムの基本的処理は三つある. (1) 順次処理 : 上から下に順番に処理する ぶんきそろ (2) 分岐処理 : 条件が揃えば, 処理する はんぷく (3) 反復処理 : 条件が揃うまで処理を繰り返す 全てのプログラムは (1) から (3) の

gengo1-11

Microsoft PowerPoint - 11.pptx

PowerPoint プレゼンテーション

情報処理Ⅰ演習

第1回 プログラミング演習3 センサーアプリケーション

Microsoft PowerPoint - exp2-02_intro.ppt [互換モード]

バイオプログラミング第 1 榊原康文 佐藤健吾 慶應義塾大学理工学部生命情報学科

Microsoft PowerPoint - handout07.ppt [互換モード]

C プログラミング演習 1( 再 ) 2 講義では C プログラミングの基本を学び 演習では やや実践的なプログラミングを通して学ぶ

Microsoft PowerPoint - 09.pptx

RX ファミリ用 C/C++ コンパイラ V.1.00 Release 02 ご使用上のお願い RX ファミリ用 C/C++ コンパイラの使用上の注意事項 4 件を連絡します #pragma option 使用時の 1 または 2 バイトの整数型の関数戻り値に関する注意事項 (RXC#012) 共用

<4D F736F F D20438CBE8CEA8D758DC03389F0939A82C282AB2E646F63>

02: 変数と標準入出力

プログラミングI第10回

Prog1_10th

プログラミング実習I

gengo1-8

Microsoft PowerPoint - 5Chap15.ppt

演算増幅器

Taro-ポインタ変数Ⅰ(公開版).j

02: 変数と標準入出力

memo

02: 変数と標準入出力

CプログラミングI

02: 変数と標準入出力

02: 変数と標準入出力

4 月 東京都立蔵前工業高等学校平成 30 年度教科 ( 工業 ) 科目 ( プログラミング技術 ) 年間授業計画 教科 :( 工業 ) 科目 :( プログラミング技術 ) 単位数 : 2 単位 対象学年組 :( 第 3 学年電気科 ) 教科担当者 :( 高橋寛 三枝明夫 ) 使用教科書 :( プロ

Microsoft Word - no12.doc

コマンドラインから受け取った文字列の大文字と小文字を変換するプログラムを作成せよ 入力は 1 バイトの表示文字とし アルファベット文字以外は変換しない 1. #include <stdio.h> 2. #include <ctype.h> /*troupper,islower,isupper,tol

講習No.8

目次

Microsoft PowerPoint - program.ppt [互換モード]

02: 変数と標準入出力

Microsoft Word - no202.docx

02: 変数と標準入出力

cp-7. 配列

Microsoft PowerPoint - 計算機言語 第7回.ppt

02: 変数と標準入出力

memo

プログラミングI第5回

02: 変数と標準入出力

PowerPoint Presentation

PowerPoint Presentation

今回のプログラミングの課題 ( 前回の課題で取り上げた )data.txt の要素をソートして sorted.txt というファイルに書出す ソート (sort) とは : 数の場合 小さいものから大きなもの ( 昇順 ) もしくは 大きなものから小さなもの ( 降順 ) になるよう 並び替えること

C 資料 電脳梁山泊烏賊塾 構造体 C++ の構造体 初めに 此処では Visual Studio 2017 を起動し 新しいプロジェクトで Visual C++ の Windows デスクトップを選択し Windows コンソールアプリケーションを作成する 定義と変数宣言 C++ に

02: 変数と標準入出力

pp2018-pp9base

02: 変数と標準入出力

Microsoft PowerPoint - 13th.ppt [互換モード]

メソッドのまとめ

Microsoft PowerPoint ppt

Prog1_6th

プログラミング及び演習 第1回 講義概容・実行制御

PowerPoint プレゼンテーション

プログラミング基礎

PowerPoint プレゼンテーション

Microsoft PowerPoint - 第3回目.ppt [互換モード]

情報処理概論(第二日目)

講習No.9

/*Source.cpp*/ #include<stdio.h> //printf はここでインクルードして初めて使えるようになる // ここで関数 average を定義 3 つの整数の平均値を返す double 型の関数です double average(int a,int b,int c){

スライド 1

Microsoft PowerPoint - ca ppt [互換モード]

JavaプログラミングⅠ

Microsoft PowerPoint - CproNt02.ppt [互換モード]

問 2 ( 型変換 ) 次のプログラムを実行しても正しい結果が得られない 何が間違いかを指摘し 正しく修正せよ ただし int サイズが 2 バイト long サイズが 4 バイトの処理系での演算を仮定する #include <stdio.h> int main( void ) { int a =

Microsoft PowerPoint - C4(反復for).ppt

program7app.ppt

デジタル表現論・第6回

Microsoft PowerPoint - 説柔5_間勊+C_guide5ï¼›2015ã•’2015æŒ°æŁŽæš’å¯¾å¿œç¢ºèª“æ¸‹ã†¿ã•‚.pptx

第9回 配列(array)型の変数

Microsoft PowerPoint - C_Programming(3).pptx

ポインタ変数

次に示す数値の並びを昇順にソートするものとする このソートでは配列の末尾側から操作を行っていく まず 末尾の数値 9 と 8 に着目する 昇順にソートするので この値を交換すると以下の数値の並びになる 次に末尾側から 2 番目と 3 番目の 1

<4D F736F F D20438CBE8CEA8D758DC F0939A82C282AB2E646F63>

1. 関数 scanf() 関数 printf() は変数の値を画面に表示しますが それに対し関数 scanf() はキーボードで入力した値を変数に代入します この関数を活用することで対話式 ( ユーザーの操作に応じて処理を行う ) プログラムを作ることができるようになります 整数の和

PowerPoint プレゼンテーション - 物理学情報処理演習

< F2D837C E95CF CF68A4A94C5816A2E6A>

PowerPoint プレゼンテーション

memo

プログラミング方法論 II 第 14,15 回 ( 担当 : 鈴木伸夫 ) 問題 17. x 座標と y 座標をメンバに持つ構造体 Point を作成せよ 但し座標 は double 型とする typedef struct{ (a) x; (b) y; } Point; 問題 18. 問題 17 の

データ構造

kiso2-09.key

Microsoft PowerPoint - 12.ppt [互換モード]

関数の動作 / printhw(); 7 printf(" n"); printhw(); printf("############ n"); 4 printhw(); 5 関数の作り方 ( 関数名 ) 戻り値 ( 後述 ) void である. 関数名 (

Microsoft Word - report#8.docx

Microsoft PowerPoint pptx[読み取り専用]

情報処理 Ⅱ 2007 年 11 月 26 日 ( 月 )

JavaプログラミングⅠ

6 関数 6-1 関数とは少し長いプログラムを作るようになると 同じ処理を何度も行う場面が出てくる そのたびに処 理を書いていたのでは明らかに無駄であるし プログラム全体の見通しも悪くなる そこで登場す るのが 関数 である 関数を使うことを 関数を呼び出す ともいう どのように使うのか 実際に見て

Java プログラミング Ⅰ 11 回目多次元配列 2 次元配列 2 次元配列配列要素が直線上に並ぶ一次元配列に対して 平面上に並ぶ配列要素をもつ配列 直観的には 2 次元配列の準備配列変数の宣言は型と識別子を指定して次のように行う 型識別子 [ ][ ]; または 型 [ ][ ] 識別子 ; 配

Microsoft Word - Cプログラミング演習(11)

始めに, 最下位共通先祖を求めるための関数 LcaDFS( int v ) の処理を記述する. この関数は値を返さない再帰的な void 関数で, 点 v を根とする木 T の部分木を深さ優先探索する. 整数の引数 v は, 木 T の点を示す点番号で, 配列 NodeSpace[ ] へのカーソル

プログラミングI第6回

Microsoft Word - no13.docx

プログラミング実習I

char int float double の変数型はそれぞれ 文字あるいは小さな整数 整数 実数 より精度の高い ( 数値のより大きい より小さい ) 実数 を扱う時に用いる 備考 : 基本型の説明に示した 浮動小数点 とは数値を指数表現で表す方法である 例えば は指数表現で 3 書く

デジタル表現論・第4回

Transcription:

7 ポインタ (P.61) ポインタを使うと, メモリ上のデータを直接操作することができる. 例えばデータの変更 やコピーなどが簡単にできる. また処理が高速になる. 7.1 ポインタの概念 変数を次のように宣言すると, int num; メモリにその領域が確保される. 仮にその開始のアドレスを 10001 番地とすると, そこから int 型のサイズ, つまり 4 バイト分の領域が確保される.1 つのアドレスには通常 1 バイト が格納されるので,10001~10004 番地が確保されることになる. &num = アドレス 10001 番地 10002 この部分に変数 num の領域が確保される. 10003 大きさは int 型,4 バイトである. 10004 10005 図 1 メモリに確保される変数の領域 変数を宣言するだけでは確保された領域の値は不定である. 次のように変数へ値を代入す ると, num = 5; 確保された 4 バイトの領域に整数,5 がセットされる. 以後, 変数名で値にアクセスできる. 別の視点として, データの先頭のアドレス (10001 番地 ) とデータ型の 2 つの情報があれ ば, 変数,mun の値にアクセスできる. ポインタはこの考え方による. 7.2 ポインタ変数の宣言 データが記憶されている領域の先頭のアドレスの情報はポインタ変数で管理される. ポ インタ変数は次のように宣言してから使用する. データ型 * 変数名 ; アスタリスク例 : int * ptr; /* int 型ポインタ変数 ptr を宣言する. * は間接演算子である.*/

変数,ptr には int 型変数のアドレスが格納される. 変数,num のアドレスをポインタ変数, ptr へ代入するときは, ptr = &num; /*num のアドレスを ptr へ代入する.&num は num のアドレスを意味する */ とする. ポインタ変数,ptr を使うと, 変数,num の内容を操作できる. 例えば num の値を 5 から 7 へ変えるときは, *ptr = 7; /* 7 を ptr の指し示すアドレス上にある領域にセットする */ 次にポインタの使用例を示す. このプログラムは変数,num のアドレスをポインタ変数, ptr で受け取り,num と ptr を使って変数の値を画面に表示する. プログラム 7-1( 演習問題 (1) のヒント ) int num = 5; /*5 を int 型変数 num にセットする */ int *ptr; /*int 型ポインタ変数 ptr を宣言する */ ptr = &num; /*num のアドレスを ptr へセットする */ printf("num = %d, &num = %x n", num, &num);/* num の値と num のアドレスを表示する */ /*%x は 16 進数での表示を意味する.( 教科書 P. 20, 表 3-1)*/ printf("*ptr = %d, ptr = %x n", *ptr, ptr);/* ptr のアドレス上の値とそのアドレスを表示する */ /* *ptr は ptr の指し示す先の値を意味する */ コンパイル リンクの手順は次のとおり. >gcc -o p7_1 p7_1.c[enter] >./p7_1[enter] 注意 : ポインタ変数を初期化しないと, その値は不定である. もし初期化なしでポインタ 変数を使用すると, システム領域のデータを書き換える恐れがある. ポインタ変数 は必ず初期化後に使用しなければならない. 7.3 関数の引数としてのポインタ ポインタが関数の引数として使える. プログラム 7-3 は変数,num のアドレスを副関数の 引数であるポインタ変数,ptr で受け取り, 副関数内で num の値を変更している.( 自動 ) 変

数は宣言した位置によってその使用できる通用範囲 ( スコープ ) が定まり, それを越えると, 変数の値を操作できない. しかし, このプログラムではポインタを使って通用範囲外の変数 にアクセスできることを示している. プログラム 7-3 void change_number(int *ptr); /* int *ptr は int * でもよい */ int num = 5; /*5 を int 型変数 num へ代入する */ printf("num = %d (BEFORE) n", num); /* num の値を画面に表示する */ change_number(&num); /* num のアドレスを引数として, 関数 cange_number へ渡す */ printf("num = %d (AFTER) n", num); void change_number(int *ptr) /* num のアドレスが ptr へセットされる */ *ptr = 7; /* 7 を ptr の指し示す先の値とする */ printf("*ptr = %d (IN) n", *ptr);/* ptr の指し示すアドレス上にある値を画面に表示する */ return; /* 戻り値は無し */ 7.4 ポインタと配列 7.4.1 ポインタと 1 次元配列 1 次元配列変数を次のように宣言する. int num[ 3 ] = 5, 8, 2 ; 仮にメモリの開始のアドレスを 10001 番地とすると, そこから 4 バイト 3 個分の領域が確保され, 値が保存される. そのイメージは次のとおり. アドレス 配列 数値 ポインタが指す先の値 &num[ 0 ] = 10001 番地 num[ 0 ] 5 * ( ptr + 0 ) 10005 num[ 1 ] 8 * ( ptr + 1 ) 10009 num[ 2 ] 2 * ( ptr + 2 ) 1000d 未割当 不定 図 2 メモリに確保される変数の値とアドレス

連続した番地に 1 次元配列のデータが順番に格納される. ポインタ変数は次のように宣言してから使用する. int * ptr; /* int 型ポインタ変数 ptr を宣言する.*/ 変数,ptr には int 型変数のアドレスが格納される. 配列変数,num のアドレスをポインタ変数,ptr へ代入するときは, ptr = num; /* ptr = &num[ 0 ] でも可 */ i 番目の配列要素,num [ i ] の値にアクセスするときは * ( ptr + i ) の表現を使う. 次にポインタと 1 次元配列の変数の関係についての例を示す. このプログラムは配列変数,num のアドレスをポインタ変数,ptr で受け取り,num と ptr を使って変数の値とそのアドレスを画面に表示する. プログラム 7-6 int num[3] = 1, 8, 2; /* 初期値を int 型配列変数 num にセットする */ int *ptr; /*int 型ポインタ変数 ptr を宣言する */ ptr = num; /* num のアドレスを ptr にセットする */ printf("num[0] = %d, num[1] = %d, num[2] = %d, n", num[0], num[1], num[2]); /*num の値を表示 */ printf("*num = %d, *(num+1) = %d, *(num+2) = %d, n", *num, *(num+1), *(num+2));/* 上に同じ */ printf("*ptr = %d, *(ptr+1) = %d, *(ptr+2) = %d n", *ptr, *(ptr+1), *(ptr+2)); /*ptr による num の表示 */ printf("num = %x, num+1 = %x, num+2 = %x n", num, num+1, num+2); /*num のアドレスを表示 */ printf("ptr = %x, ptr+1 = %x, ptr+2 = %x n", ptr, ptr+1, ptr+2); /*ptr のアドレスを表示 */ 7.4.2 関数の引数として配列を与える場合 ( 省略 ) 配列変数のポインタが関数の引数として使える. プログラム 7-7 は,10 個の高さのデータをキーボードから入力する ( そのデータは配列変数,height に格納される ). 次に height のアドレスを引数をとして, 高さの平均を求める関数,average を呼ぶ. 関数内で平均を求め, その値を画面に表示する. プログラム 7-7 float average(float *h); /* float *h は float * でもよい */

float ave, height[10]; /*float 型変数を 2 つ宣言する */ int i; /*int 型変数を宣言する */ for(i=0; i<10; ++i) /*10 回ループをまわす */ printf("input height.(cm) n"); /* 画面に入力を促すための表示をする */ scanf("%f", &height[i]); /* キーボードから数値を入力する */ ave = average(height); /* 引数として配列 height を関数 average へ渡す */ printf("average is %6.1f n", ave); /* 平均値を表示する */ float average(float *h) /* 平均値を計算する関数.height[0] のアドレスが h へセットされる */ int i; /*int 型変数を宣言する */ float av, total = 0.0; /*float 型の変数を2つ宣言する */ for(i=0; i<10; ++i) /*10 回ループを回す */ total += *(h+i); /* 総計を求める.*/ av = total/10.0; /* 平均値を求める */ return(av); /* 平均値を ave へセットする */ 7.4.3 ポインタと 2 次元配列 ( ポインタと 2 次元配列の対応 ) 2 次元配列変数を次のように宣言する. int num[2][3] = 1, 2, 3, 4, 5, 6 仮にメモリの開始のアドレスを 10001 番地とすると, そこから 4 バイト 6 個分の領域が確 保され, 値が保存される. そのイメージは次のとおり. 配列 数値 ポインタが指す先の値 &a[ 0 ] = 10001 番地 num [ 0 ][ 0 ] 1 * ( num + 3 0 + 0 ) 10005 num [ 0 ][ 1 ] 2 * ( num + 3 0 + 1 ) 10009 num [ 0 ][ 2 ] 3 * ( num + 3 0 + 2 ) 1000d num [ 1 ][ 0 ] 4 * ( num + 3 1 + 0 ) 10011 num [ 1 ][ 1 ] 5 * ( num + 3 1 + 1 ) 10015 num [ 1 ][ 2 ] 6 * ( num + 3 1 + 2 ) 10019 未割当 不定 図 3 メモリに確保される変数の値とアドレス

連続した番地に 2 次元配列のデータが順番に格納される. M 行 N 列の配列において,i 行 j 列の配列要素を指すポインタは次式で表現される. 配列名 + N i + j 例えば配列変数,num[2][3] についてのそれは次のとおりである. num + 3 i + j 次にポインタと 2 次元配列の変数の関係についての例を示す. プログラム 7-8 は, 最初に配列変数,result に 3 教科の成績をセットする. 配列変数,result と average のアドレスを引数として, 副関数,gt_ave を呼ぶ. そこでは各教科の平均点の計算を行う. 最後に 3 教科の平均点を表示する.( 教科書の式とプログラム 7-8 の i と j の行と列の対応は反対なので注意する.) プログラム 7-8 void get_ave(float *score, float *ave); /* 副関数のプロトタイプ宣言 */ /*float 型 2 次元配列を宣言し,5 名分の英語, 数学, 国語の点数をセットする */ float result[5][3] = 50, 65, 45,77, 80, 90,30, 40, 50,75, 92, 80,65, 69, 90; float average[3]; /* float 型 1 次元配列を宣言する.3 教科の平均値を扱う */ get_ave(result, average); /* 配列名を引数で与えて, 関数を呼ぶ */ /*3 教科の平均値を表示する */ printf("average is %4.1f(Eng.), %4.1f(Math), %4.1f(Jap) n", average[0], average[1], average[2]); void get_ave(float *score, float *ave) /*3 教科の平均値を求める関数 */ int i, j; /*int 型変数を2つ宣言する */ float total[3]; /*float 型配列変数を宣言する. データの累積が格納される.*/ for(i=0; i<3; ++i) /*3 教科についての計算.iは列を意味する.*/ total[i] = 0.0; /* 総計の値をリセットする */ for(j=0; j<5; ++j) /* 5 名についての計算.jは行を意味する.*/ total[i] += *(score + 3*j + i); /* 教科書の式と比べるとiとjの対応が反対である */ for(i=0; i<3; ++i) *(ave + i) = total[i]/5.0; /* 平均を求めている */