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

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

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

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

Microsoft Word - 3new.doc

Microsoft PowerPoint - 11.pptx

PowerPoint プレゼンテーション

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

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

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

Microsoft Word - no202.docx

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

Microsoft Word - no11.docx

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

プログラミング実習I

PowerPoint Presentation

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

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

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

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

ゲームエンジンの構成要素

gengo1-11

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

Microsoft PowerPoint - 説明2_演算と型(C_guide2)【2015新教材対応確認済み】.pptx

情報処理演習 B8クラス

Microsoft PowerPoint ppt

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

Microsoft PowerPoint - lec10.ppt

情報処理Ⅰ演習

gengo1-2

Microsoft Word - no02.doc

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

PowerPoint プレゼンテーション

memo

PowerPoint Presentation

スライド 1

講習No.12

02: 変数と標準入出力

8 / 0 1 i++ i 1 i-- i C !!! C 2

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

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

gengo1-10

プログラミング実習I

講習No.9

02: 変数と標準入出力

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

PowerPoint プレゼンテーション

Microsoft PowerPoint - kougi7.ppt

Microsoft PowerPoint - prog04.ppt

演算増幅器

<4D F736F F D20438CBE8CEA8D758DC F0939A82C282AB2E646F63>

02: 変数と標準入出力

関数の中で宣言された変数の有効範囲はその関数の中だけです さっきの rectangle _s で宣言されている変数 s は他の関数では使用できません ( 別の関数で同じ名前の変数を宣言することはできますが 全く別の変数として扱われます このように ある関数の中で宣言されている変数のことをその関数の

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

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

Microsoft PowerPoint - prog03.ppt

第2回講義:まとめ

PowerPoint プレゼンテーション

< F2D837C E95CF CF68A4A94C5816A2E6A>

Microsoft Word - no103.docx

Prog1_10th

C言語7

memo

Taro-リストⅠ(公開版).jtd

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

PowerPoint Presentation

Taro-ファイル処理(公開版).jtd

kiso2-09.key

目次

memo

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

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

<4D F736F F D20438CBE8CEA8D758DC03389F0939A82C282AB2E646F63>

Microsoft Word - no12.doc

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

物質工学科 田中晋

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

プログラミング演習3 - Cプログラミング -

Microsoft Word - no15.docx

プログラミング基礎

Microsoft PowerPoint - kougi2.ppt

プログラミング基礎

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

プログラミング演習3 - Cプログラミング -

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

プログラミング基礎

ファイル入出力

講習No.8

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

Microsoft Word - report#8.docx

C 言語第 3 回 2 a と b? 関係演算子 a と b の関係 関係演算子 等しい a==b 等しくない a!=b より大きい a>b 以上 a>=b より小さい a<b 以下 a<=b 状態 真偽 値 条件が満たされた場合 TRUE( 真 ) 1(0 以外 ) 条件が満たされなかった場合 F

Prog1_12th

gengo1-8

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

2006年10月5日(木)実施

Microsoft Word - no204.docx

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

2 ASCII コードと文字型変数 2-1 ASCII コード 文字 コードコードコードコードコードコードコードコード文字文字文字文字文字文字文字 10 進 10 進 10 進 10 進 10 進 10 進 10 進 10 進 0 16 SP P 80 ` 96 p 112

Microsoft PowerPoint - class04.ppt

ファイル入出力

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

Transcription:

第 11 回ポインタの基礎 ( アドレスとポインタ ) 1

今回の目標 C 言語におけるポインタを理解する 変数のアドレスを理解する ポインタ型を理解する アドレス演算子 参照演算子の効果を理解する NULL というアドレスを理解する 複数の関数内で変数のアドレスを表示するプログラムを作成する 2

ポインタ ポインタとは 変数のアドレスを入れる変数である ポインタの型はこれまでのどの型 (char,int,double) とも異なる 3

変数とアドレス コンピュータのメモリには すべてアドレスがある アドレスメモリ変数名 0x0000 番地 C 言語を用いたプログラムでは プログラマがアドレスを管理できる 0x**** c char c; 1 バイト 0x++++ 0xFFFF 番地 ii int i; 4 バイト 変数宣言すると その変数のためにメモリが割り当てられる 変数名は メモリの一区画につけられた名前である 4

アドレス演算子 & &: 変数に割り当てられたメモリの先頭アドレスを求める演算子 前置の単項演算子 例 書式 & 変数名 int age; scanf("%d",&age); double height; scanf("%lf",&height); scanf( の変換仕様 ) では 変数のアドレスを指定すると そのアドレスが割り当てられている変数 ( メモリ ) に標準入力から値を読み込む 5

アドレスを指定するscanf 文の仕様書式 scanf("%c", 文字をいれる変数のアドレス ) scanf("%d", 整数をいれる変数のアドレス ) scanf("%lf", 実数をいれる変数のアドレス ) 例 char moji; scanf("%c",&moji); & がついているのでアドレス アドレス メモリ 変数名 0x0000 番地 0x**** moji 標準入力 scanf 文 0x**** 番地に文字を書き込んで 6

アドレスを表示する printf 文の仕様 printf 文には アドレスを表示するための変換仕様がある 例 %p 変数のアドレスを表示させる書式 char moji; j; printf("%p",&moji); & がついているのでアドレス アドレス ( 型の区別無し ) 16 進数で表示される アドレス変数の中身 ( 値 ) メモリ 変数名 を表示させる書式 char moji; printf("%c",moji); 文字として表示される & がついていないので中身 ( 値 ) 0x**** %p moji 標準出力 %c 標準出力 7

変数名(値)レスイメージ アド中身0x**** 番地 a 0x**** 0x++++ a b 0x++++ 番地 b 0x#### c 0x#### 番地 c char 型は 1 バイト 8

鈴木田藤イメージ 入れ物 ( 建物 ) における名前と番地 ( 住所 ) と中に入っている物中に入っている値佐変数における変数名とアドレスと TV PC 中クーラー 1-23-4 1-23-5 1-23-6 1-23-4 1-23-5 1-23-6 a b c 0x**** 番地 0x++++ 番地 0x#### 番地 9

アド変数名( 値)イメージ レス中身0x**** 番地 i 0x**** i 0x++++ 番地 j 0x++++ C j 0x#### 番地 k 0x#### k int 型は 4 バイト 10

中身( 値変数名アドイメージ スレ0x**** )0x**** 番地 x 0x x 0x++++ 番地 y 0x++++ y 0x#### 番地 z double 型は 8 バイト 0x#### z 11

練習 1 /* address.c アドレス表示実験 */ #include <stdio.h> int main() { /* 変数宣言 */ char a; char b; int i; int j; double x; double y; /* 代入 */ a='a'; b='b'; i=1; j=2; x=0.1; y=0.2; 02 /* 次へ続く */ 12

} printf("char 型の変数のアドレス n"); printf("a:%p p b:%p n",&a,&b);, printf("char 型の変数の中身 n"); printf("a:%c b:%c n",a,b); printf(" n"); ") printf("int 型の変数のアドレス n"); printf("i:%p j:%p n",&i,&j); printf("int 型の変数の中身 n"); printf("i:%d j:%d n",i,j); printf(" n"); printf("double 型の変数のアドレス n"); printf("x:%p x:%p n",&x,&y); &y); printf("double 型の変数の中身 n"); printf("x:%f y:%f n",x,y); return 0; 13

ポインタの宣言 変数のアドレスを入れるための変数 ( ポインタ ) の用意の仕方 例 宣言 データ型 * ポインタの名前 ; char *p; int *q; double *r; p q 文字型の変数の整数型の変数の実数型の変数のアドレス専用アドレス専用アドレス専用 ポインタ= 変数のアドレスを入れるための入れ物 ( ただし 用途別 ) p は (char *) 型の変数と考えてもよい char 型と (char *) 型は異なる型 r 14

田中鈴木イメージ ( 種類別の ) 建物対応変数 ( の型 ) 住所アドレス ( ある型の変数を指す ) ポインタ ( 種類別の ) アドレス帳佐藤民家専用のアドレス帳 1-23-4 1-23-5 1-23-6 1-23-4 工場専用の 工場 A 工場 B 工場 C アドレス帳 2-46-8 2-46-9 2-46-10 2-46-10 商店 軒 屋 店専用のアドレス帳 3-6-9 3-6-8 3-6-7 3-6-8 15

間接演算子 * ( ポインタとポインタが指す変数 ) ポインタに 変数のアドレスを代入すると 間接演算子 * でそのポインタが指す変数の値を参照できる 書式 *: ポインタに格納されているアドレスに割り * ポインタ当てられている変数を求める演算子 前置の単項演算子例 int i; int *p; /* ポインタ */ p=(&i); /* p には i のアドレスが入る */ ポインタ pがある変数 yのアドレスを蓄えているとき ポインタpは変数 yを指すという あるいは pは変数 yへのポインタであるという 16

間接演算子を用いたメモリアクセスメp アドレス変数名モリスこれまでのアク 0x00ffa900 moji p * セス方法 変数名でアクセス char moji; char moji; char *p; printf( %c,moji); p=&moji; printf( %c,*p); ポインタを用いたアクセス方法 ポインタ名と間接演算子を用いてアクセスする アドレスの役割に注意する 17

ポインタによる変数の別名 ポインタpがある変数 yのアドレスを蓄えているとき (*p) はあたかも変数 y のように振舞う char a; char b; char *p; p=(&a);/* p は a を指す */ b=(*p); /* これは b=a; と同じ */ (*p)=b; /* これは a=b; と同じ */ 18

中身イメージ char a; moji='a'; アレスドh * 名( 値)変数char *p; p moji 0x00ffa900 moji 0x00ffa900 p=(&moji); *p moji 0x00ffa900 p 19

イメージ プログラムを図で説明するときには アドレスを数字で表さずに 矢印でポインタをあらわすことがある あ 変数宣言 ( 変数の用意 ) int i; int *p; p i アドレス代入 p p=(&i); i 20

メモリ複数の別名 double x=0.1; 01 スdouble *q; double *r; q=&x; r=&x; *r=0.2; q r 0x00ffbff0 アドレx 変数名*r=0.2; x *q *r x *r *q 0x00ffbff0 0x00ffbff0 21

NULL というアドレス どの変数も指さない特別なアドレスを NULL として表す int *p; /*int 型を指すポインタ */ double *q; /*double 型を指すポインタ */ /* ポインタへ NULL を代入 */ このように p=null; どんな型の変数を指す q=null; ポインタへも NULL を代入できる int *p; p=null; NULLを格納するポインタ /* 次は間違い */ へは間接演算子を用いる *p=1; ことはできない 22

練習 2 /* test_pointer.c ポインター実験コメント省略 */ #include <stdio.h> int main() { /* 変数宣言 */ int i; /* 整数が入る変数 */ int j; int *p; /* アドレスが入る変数 ( ポインタ )*/ / int *q; /* 代入 */ i=1; j=2; /* 次へ続く */ 23

/* 続き */ /* 実験操作 */ p=(&i); /* ポインタ pへ変数 iのアドレスを代入 */ q=(&j); /* ポインタqへ変数 jのアドレスを代入 */ /* 続き */ printf(" アドレス代入直後 n"); printf("iの中身は %d n",i); printf("iのアドレスは %p n",&i); printf( p p の中身は %p n",p); printf( pの指す変数の中身は %d n n",*p); printf("j の中身は %d n",j); printf("jのアドレスは %p n",&j); printf( qの中身は %p n",q); printf( q の指す変数の中身は %d n n n",*q); "* /* 次へ続く */ 24

/* 続き */ /* ポインタによる演算 */ (*q)=(*q)+(*p); ) ) printf("(*q)=(*q)+(*p); 実行 n"); printf(" n"); printf("iの中身は %d n",i); printf("i のアドレスは %p n",&i); printf( pの中身は %p n",p); printf( pの指す変数の中身は %d n",*p); printf(" n n"); printf("jの中身は %d n",j); printf("j のアドレスは %p n",&j); printf( qの中身は %p n",q); printf( qの指す変数の中身は %d n",*q); } return 0; 25

演算子 & と * の結合力 演算子 & * の結合力は 算術演算子よりつよく よくインクリメント演算やデクリメント演算よりよわい ++ > > / > &( アドレス演算子 ) + -- *( 間接演算子 ) *( 算術演算子 ) - *p++; *p+1; は *(p++); (*p)+1; の意味 1 つの式内でインクリメント演算子と間接演算子を使うときには 括弧を用いて意図を明確にすること 26

各種変数のアドレスを表示するプログラム /* 作成日 :yyyy/mm/dd 作成者 : 本荘太郎学籍番号 :B0zB0xx ソースファイル :print_address.c c 実行ファイル :print_address 説明 : 変数とアドレスの関係を理解するためのプログラム 複数の関数内でアドレスを表示する 入力 : 標準入力から2つの整数値を入力する 出力 : 標準出力に以下を出力する main 関数ローカル変数のアドレスと値, main 関数以外のローカル変数のアドレスと値 仮引数のアドレスと値 /* 次のページに続く */ 27

/* 続き */ /* ヘッダファイルの読み込み */ #include <stdio.h> /* マクロの定義 */ /* このプログラムでは マクロは用いない は用いない */ /* グローバル変数の宣言 */ /* このプログラムでは グローバル変数は用いない */ /* プロトタイプ宣言 */ /* 変数のアドレスを表示する関数 */ void function(int t data1); /* 次のページに続く */ 28

/* 続き */ /*main 関数 */ int main() { /* ローカル変数宣言 */ int data1; /* 入力整数 1*/ int data2; /* 入力整数 2*/ int *p; /* ポインタ */ /* 入力処理 */ printf("data1=?"); scanf("%d",&data1); printf("data2=?"); scanf("%d",&data2); 29

/* 続きポインタの設定 */ p=(&data2); /* 関数呼び出し前 */ /* 変数の中身と変数アドレスの表示 */ printf( main 関数内での表示 n ); printf( 関数 function 呼び出し前 n ); printf( &data1=%10p,&data1); printf( data1=%2d n,data1); printf( &data2=%10p,&data2); printf( data2=%2d n,data2); printf( &p=%10p,&p); printf( p=%10p,p); printf( *p=%2d n n,*p); /* 関数呼び出し */ function(data1); /* 次に続く */ 30

/* 続き */ /* 関数呼び出し後 */ /* 変数の中身と変数アドレスの表示 */ printf( main 関数内での表示 n ); printf( 関数 function 呼び出し後 n ); printf( &data1=%10p,&data1); printf( data1=%2d n,data1); printf( &data2=%10p,&data2); printf( data2=%2d n,data2); printf( &p=%10p,&p); printf( p=%10p,p); printf( *p=%2d n n,*p); * return 0; /* 正常終了 */ } /*main 関数終了次に続く */ 31

/* ローカル変数の値とローカル変数のアドレスを表示する関数仮引数 data1:main 関数から値を受け取る 仮引数のアドレスを調べるために用意してある 戻り値 : なし */ void function(int data1) { /* ローカル変数宣言 */ int data2; /* 整数型の変数 main 関数内にある変数と同じ名前にしてある */ int * p; /* ポインタ main 関数内にあるポインタと同じ名前にしてある */ /* 処理内容の通知 */ printf( function 実行中 n"); /* 次に続く */ 32

/* 続きポインタの設定 */ p=(&data2); /* 変数の中身と変数アドレスの表示 */ printf( 関数 function 内での表示 n ); printf( &data1=%10p,&data1); printf( data1=%2d n,data1); printf( &data2=%10p,&data2); printf( data2=%2d n,data2); printf( &p=%10p,&p); & printf( p=%10p,p); printf( *p=%2d n n,*p); return; } /*function 関数終了 */ /* 全プログラム (print_address.c) i t ) 終了 */ 33

実行例 $./print_address < print_address.in main 関数内での表示関数 function 呼び出し前 &data1=0xbfba3160 data1= 3 &data2=0xbfba315c data2= 4 &p=0xbfba3158 p=0xbfba315c *p=4 function 実行中関数 function 内での表示 &data1=0xbfba3140 data1= 3 &data2=0xbfba3134 data2=-1208557580 &p=0xbfba3130 p=0xbfba3134 *p =-1208557580 main 関数内での表示関数 function 呼び出し後 &data1=0xbfba3160 data1= 3 &data2=0xbfba315c data2= 4 &p=0xbfba3158 p=0xbfba315c *p=4 $ 34