Microsoft Word - no202.docx

Similar documents
Microsoft Word - no103.docx

Microsoft Word - no11.docx

Microsoft Word - no15.docx

Microsoft Word - no12.doc

Microsoft PowerPoint - 11.pptx

Microsoft Word - no14.docx

02: 変数と標準入出力

02: 変数と標準入出力

PowerPoint プレゼンテーション

Prog1_10th

Microsoft Word - no13.docx

Microsoft Word - 3new.doc

02: 変数と標準入出力

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

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

02: 変数と標準入出力

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

<4D F736F F D20438CBE8CEA8D758DC03389F0939A82C282AB2E646F63>

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

PowerPoint プレゼンテーション

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

ファイル入出力

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

今までの復習 プログラムで最低限必要なもの 入力 ( キーボードから ファイルから ) 出力 ( 画面へ ファイルへ ) 条件分岐 : 条件の成立 不成立により 異なる動作をする 繰り返し : 一定の回数の繰返し 条件成立の間の繰返し 関数の定義 関数の呼び出し C ではそれ以外に ポインタ データ

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

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

Microsoft Word - no204.docx

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

ファイル入出力

Microsoft Word - no206.docx

02: 変数と標準入出力

Microsoft PowerPoint - C言語の復習(配布用).ppt [互換モード]

プログラミング基礎

Microsoft Word - 05

gengo1-11

PowerPoint プレゼンテーション

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

プログラミング実習I

講習No.12

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

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

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

情報処理Ⅰ演習

kiso2-09.key

PowerPoint Presentation

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

Microsoft Word - no205.docx

ポインタ変数

memo

演算増幅器

Microsoft PowerPoint - lec10.ppt

Prog1_6th

演習課題No12

CプログラミングI

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

講習No.8

1. 入力した文字列を得る 1.1. 関数 scanf() を使う まずは関数 scanf() を使ったプログラムを作ってみましょう 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: #include<stdio.h> #define SIZE 128 main(

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

memo

文字列 2 前回の授業ではコンピュータ内部での文字の取り扱い 文字型の変数 文字型変数への代入方法などを学習した 今回は 前回に引き続き 文字処理を学習する 内容は 標準入出力 ( キーボード ディスプレイ ) での文字処理 文字のファイル処理 文字を取り扱うライブラリ関数である 標準入出力 Lin

Microsoft PowerPoint - 5Chap15.ppt

Prog1_15th

< F2D837C E95CF CF68A4A94C5816A2E6A>

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

Microsoft PowerPoint ppt

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

Microsoft PowerPoint - prog07.ppt

プログラミング実習I

Prog1_6th

02: 変数と標準入出力

Microsoft PowerPoint - prog03.ppt

Microsoft PowerPoint - prog04.ppt

02: 変数と標準入出力

また 初期化について 以下のサンプルコードのように指定すれば 定義時に値を代入できます * オマケ配列は同名で複数個の箱を用意出来ます 同名ではありますが それぞれは別々の個体であるわけです また この複数個の変数は メモリ上に連続で確保されます 2. 文字と文字列 C 言語では文字と文字列は異なる

C言語7

Microsoft Word - no02.doc

講習No.9

Microsoft Word - no15.docx

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

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

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

Microsoft PowerPoint - å®�æ−•è©¦é¨fi3ㆮ対ç�Œ.pptx

情報工学実験 C コンパイラ第 2 回説明資料 (2017 年度 ) 担当 : 笹倉 佐藤

FORTRAN( と C) によるプログラミング 5 ファイル入出力 ここではファイルからデータを読みこんだり ファイルにデータを書き出したりするプログラムを作成してみます はじめに テキスト形式で書かれたデータファイルに書かれているデータを読みこんで配列に代入し 標準出力に書き出すプログラムを作り

C言語講座 後半

PowerPoint プレゼンテーション

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

デジタル表現論・第4回

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

初歩のC言語ターミナル_2014_May.pages

Java プログラミング Ⅰ 3 回目変数 変数 変 数 一時的に値を記憶させておく機能型 ( データ型 ) と識別子をもつ 2 型 ( データ型 ) 変数の種類型に応じて記憶できる値の種類や範囲が決まる 型 値の種類 値の範囲 boolean 真偽値 true / false char 2バイト文

1. 入力した正の整数を降順に並べ換えて出力するプログラムを作成せよ プログラムは個別にコンパイルし make コマンドで実行すること 入力データは 50 以下とし 以下の数が混在しているとする 16 進数 : 先頭 1 文字が x または X( エックスの小文字か大文字 ) 8 進数 : 先頭 1

スライド 1

C-programming_kouza4(2007)

gengo1-8

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

gengo1-10

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

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

データ構造

Transcription:

1.4 ポインタと配列 ポインタ変数は前回説明したように 値の入っているアドレスを示す変数です では 配列はどの ようにメモリ上に格納されるか調べてみましょう ex07.c /* ポインタと配列の関係 */ int a[3]={1, 2, 3; /* int 型の大きさ 3 の配列として宣言 */ int *i; /* int 型へのポインタとして宣言 */ double x[3] = {1.0, 2.0, 3.0; /* double 型の大きさ 3 の配列として宣言 */ double *y; /* double 型へのポインタとして宣言 */ i = &a[0]; /* ポインタ変 i に a[0] の番地を代入 */ y = &x[0]; /* ポインタ変 j に x[0] の番地を代入 */ printf("&a[0] = %p n", &a[0]); /* a[0] の番地を表示 */ printf("&a[1] = %p n", &a[1]); /* a[1] の番地を表示 */ printf("&a[2] = %p n", &a[2]); /* a[2] の番地を表示 */ printf("i = %p n", i); /* ポインタ変数 i の値を表示 */ printf("*i = %d n", *i); /* ポインタ変数 i が示す番地の内容を表示 */ i++; /* i をインクリメントする */ printf("i = %p n", i); /* ポインタ変数 i の値を表示 */ printf("*i = %d n", *i); /* ポインタ変数 i が示す番地の内容を表示 */ printf("&x[0] = %p n", &x[0]); /* x[0] の番地を表示 */ printf("&x[1] = %p n", &x[1]); /* x[1] の番地を表示 */ printf("&x[2] = %p n", &x[2]); /* x[2] の番地を表示 */ printf("y = %p n", y); /* ポインタ変数 y の値を表示 */ printf("*y = %f n", *y); /* ポインタ変数 y が示す番地の内容を表示 */ y++; /* y をインクリメントする */ printf("y = %p n", y); /* ポインタ変数 y の値を表示 */ printf("*y = %f n", *y); /* ポインタ変数 y が示す番地の内容を表示 */ ここで注意すべき点は次のとおりです 配列は連続したアドレスのメモリ上に確保されている ポインタ変数に対し ++ や + などの演算を使うと 変数の大きさを考えて変化する ( もちろん -- - も同様) 8

このことを考えると次のようなことがわかります アパートの例に戻って説明します まず このアパートの 1 号室をさすポインタ x を考えてみましょう ここで x++ とすると次の番地をさすのですから x は 2 号室をさすことになります つまり 1 を加えること が 次の部屋 (= 次のアドレス ) を意味します 4 号室四谷 5 号室五代 6 号室六本木 1 号室一ノ瀬 2 号室二階堂 3 号室三鷹 次に このアパートをさす配列 y を考えてみましょう y[0] が 1 号室 y[1] が 2 号室 y[5] が 6 号室を意味します つまり [ ] の中の数字が 1 増える ことが 次の部屋 (= 次のアドレス ) を意味します こう考えてみると 1 増やす ということがポインタにとっても配列にとっても同じ意味を持っ ていることに気づくはずです 実は C ではポインタも配列も同じものなのです 次の例題をやって みましょう ex08.c /* ポインタと配列 */ int a[] = {36, 84, 65, 55, 92; int *x; printf("&a[0] = %p n", &a[0]); /* a[0] のアドレスを表示 */ printf("a = %p n", a); /* a を表示 */ printf("*a = %d n", *a); /* a の指すアドレスの値の表示 */ printf("a[1] = %d n", a[1]); /* a[1] の値の表示 */ printf("*(a+1) = %d n", *(a + 1)); /* a+1 の指すアドレスの値の表示 */ x = a; printf("x[1] = %d n", x[1]); /* x[1] の値の表示 */ printf("*x = %d n", *x); /* a の指すアドレスの値の表示 */ printf("*(x+1) = %d n", *(x + 1)); /* x+1 の指すアドレスの値の表示 */ ポインタ変数 x に配列 a を代入します これでポインタ変数 x が配列 a をあらわすようになりました 詳しく言えば x の値は a[0] のアドレスということになります すると x[1] のような配列が使えるのです x はポインタ変数のはずでしたが 配列としても使えるわけです 逆に配列であった a をポインタ変数のようにも使えます 9

配列とポインタの違いは 配列で宣言すると 値を入れるためのメモリが確保される ポインタで宣言すると 値を入れるためのメモリが確保されない だけです ほかは大きな違いはありません 値を入れるための場所を確保する必要があるときには 配列を使う必要があることさえ知っていれば よいでしょう 部屋一刻館 [6]; 部屋 という型の大きさ 6 の配列を宣言すれば 6 部屋のアパートが建てられる 住人が住める 一刻館は ここ 部屋 * 一刻館 ; 部屋 という型のポインタ変数を宣言しても一刻館をさす場所が用意されるだけ 住人は住めない あっちってどこだ 一刻館はあるんだろうか? 一刻館はあっち C 言語においては配列は一種のポインタなのです ですから 関数の引数として配列を渡したとき 関数の中で配列の値を変更すると 呼び出しもとでも配列の値が変更されていたのは 引数がポイン タになっていたので当たり前のことなのです 以上のことを知れば 配列でできることはポインタでできることとなります 10

まず 簡単な例をいくつかあげます まずは 整数の和をポインタで実現させる例です ex09.c /* ポインタと配列 ( 整数の和 ) */ int sum_array(int[], int); int sum_pointer1(int *, int); int sum_pointer2(int *, int *); int x[10] = {36, 84, 65, 55, 92, 83, 71, 63, 87, 79; printf(" 合計 ( 配列版 ) = %d n", sum_array(x, 10)); printf(" 合計 ( ポインタ版 1) = %d n", sum_pointer1(x, 10)); printf(" 合計 ( ポインタ版 2) = %d n", sum_pointer2(x, x + 9)); /* 合計を計算する関数 ( 配列版 )*/ int sum_array(int array[], int len) { int i, sum = 0; for(i = 0; i < len; i++) { sum += array[i]; return(sum); /* 合計を計算する関数 ( ポインタ版その 1)*/ int sum_pointer1(int *pointer, int len) { int i, sum = 0; for(i = 0; i < len; i++) { sum += *pointer; pointer++; return(sum); /* 合計を計算する関数 ( ポインタ版その 2)*/ int sum_pointer2(int *x, int *last) { int sum = 0; for( ; x <= last; x++) { sum += *x; return(sum); 11

文字列は終了を表す文字 ' 0' があるので簡単です 文字列の長さを調べる関数をあげます char 型へのポインタを使います ex10.c /* 文字列の長さを調べる関数 */ int length_array(char[]); int length_pointer(char *); char string[81]; printf(" 文字列を入力してください : "); scanf("%80s", string); /* 最大 80 文字まで読み込む */ printf("%s n", string); printf("%d 文字 ( 配列版 ) n", length_array(string)); printf("%d 文字 ( ポインタ版 ) n", length_pointer(string)); return (0); /* 文字列の長さを調べる関数 ( 配列版 ) */ int length_array(char str[]) { int i, len = 0; for(i = 0; str[i]!= ' 0'; i++) { len++; return(len); /* 文字列の長さを調べる関数 ( ポインタ版 ) */ int length_pointer(char *str) { int len = 0; for( ; *str!= ' 0'; str++) { len++; return(len); 12

練習問題 6.3 ポインタを用いて文字列の小文字を大文字に変換する関数 to_upper を作成せよ ただし ポイン タを使い 配列は使わないこと また 変換した個数を戻り値で戻すように作成すること ex11.c /* ポインタを用いて大文字変換 */ int to_upper(char *); char string[81]; int i; printf(" 文字列を入力してください : "); scanf("%80s", string); /* 最大 80 文字まで読み込む */ printf(" 変換前 n%s n", string); i = to_upper(string); printf(" 変換後 n%s n", string); printf("%d 文字変換しました n", i); return (0); int to_upper(char *str) { 練習問題 6.4 2 つのポインタを受け取り 一つ目のポインタから二つ目のポインタの間 ( 両端を含む ) から最大値 を指すポインタを返す関数を完成させなさい それを用いた選択ソート ( 最大値ソート ) のプログラ ムを完成させなさい ex12.c /* 選択ソート ( 最大値ソート ) */ #define LENGTH 10 int *nmax(int *x, int *last); void input_data(int *x, int len); void selection_sort(int *x, int len); void exchange(int *x, int *y); 13

int main(void){ int n[length], i; input_data(n, LENGTH); selection_sort(n, LENGTH); for(i = 0; i < LENGTH; i++) { printf("%3d", n[i]); printf(" n"); /* 選択ソート */ void selection_sort(int *x, int len) { int *i, *imax; for(i = x + len - 1; i > x; i--) { imax = nmax(x, i); if(i!= imax) { exchange(imax, i); int *nmax(int *x, int *last) { /* 値の交換 */ void exchange(int *x, int *y) { int t; /* 値を一時的に保存する変数 */ t = *x; *x = *y; *y = t; /* x と y の指すアドレスに格納された値を交換 */ /* データの入力 */ void input_data(int *x, int len) { int i; for(i = 0; i < len; i++) { printf(" 配列番号 %d: ", i); scanf("%d", x++); 14