memo

Similar documents
memo

memo

memo

memo

gengo1-11

Microsoft PowerPoint - 09.pptx

PowerPoint プレゼンテーション

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

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

Microsoft PowerPoint - lec10.ppt

情報処理Ⅰ演習

プログラミング実習I

memo

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

Microsoft PowerPoint ppt

program7app.ppt

Microsoft PowerPoint - prog06.ppt

Microsoft PowerPoint - 11.pptx

cp-7. 配列

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

Microsoft PowerPoint - prog07.ppt

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

PowerPoint プレゼンテーション

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

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

Microsoft Word - 3new.doc

プログラミングI第10回

PowerPoint Presentation

kiso2-09.key

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

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

Prog1_10th

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

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

Microsoft Word - no202.docx

PowerPoint プレゼンテーション

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

memo

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

演習課題No12

02: 変数と標準入出力

プログラミング基礎

講習No.12

DVIOUT

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

演算増幅器

Prog1_15th

Microsoft PowerPoint pptx[読み取り専用]

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

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

PowerPoint プレゼンテーション

メソッドのまとめ

02: 変数と標準入出力

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

02: 変数と標準入出力

PowerPoint プレゼンテーション

PowerPoint プレゼンテーション

PowerPoint Presentation

CプログラミングI

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

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

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

Microsoft PowerPoint - kougi9.ppt

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

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

02: 変数と標準入出力

Microsoft Word - no12.doc

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

02: 変数と標準入出力

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

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

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

02: 変数と標準入出力

02: 変数と標準入出力

Microsoft PowerPoint pptx

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

02: 変数と標準入出力

C言語講座

02: 変数と標準入出力

02: 変数と標準入出力

Microsoft PowerPoint - kougi7.ppt

PowerPoint プレゼンテーション

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(

PowerPoint Presentation

< F2D837C E95CF CF68A4A94C5816A2E6A>

Microsoft PowerPoint pptx

C 言語第 7 回 掛け算 (multiply number) ìz1 = x1 + iy1 í îz = x + iy 割り算 (devide number) ( )( ) ( ) Þ z z = x + iy x + iy = x x - y y + i y x + x y

slide5.pptx

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

1 return main() { main main C 1 戻り値の型 関数名 引数 関数ブロックをあらわす中括弧 main() 関数の定義 int main(void){ printf("hello World!!\n"); return 0; 戻り値 1: main() 2.2 C main

講習No.10

gengo1-8

PowerPoint プレゼンテーション

デジタル表現論・第6回

memo

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

C-programming_kouza4(2007)

gengo1-10

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

第2回

Transcription:

計数工学プログラミング演習 ( 第 3 回 ) 2017/04/25 DEPARTMENT OF MATHEMATICAL INFORMATICS 1

内容 ポインタの続き 引数の値渡しと参照渡し 構造体 2

ポインタで指されるメモリへのアクセス double **R; 型 R[i] と *(R+i) は同じ意味 意味 R double ** ポインタの配列 ( の先頭 ) へのポインタ R[i] double * i 行目を表す配列 ( の先頭 ) へのポインタ R[i][j] double i 行 j 列の要素 i は負の整数でもいいが, メモリを破壊しないように注意する double *X; は実数へのポインタだが, 同時に配列の先頭へのポインタとも解釈できるので紛らわしいので注意 3

ポインタの演算 整数へのポインタを 1 増やすと, アドレスが整数 1 個分増える 配列の要素は連続したアドレスに格納されるので, ポインタを 1 ずつ増やすと配列の要素に順番にアクセスできる 配列の長さを超えてもポインタは増やせるのでバグに注意 コンパイルはできるが実行するとエラー int A[10]; for (i=0; i<10; i++) A[i] = 0; int *p, A[10]; p = A; for (i=0; i<10; i++) *p = 0; p += 1; 4 *p++ = 0; とも書ける

変数を格納するメモリ領域 /* test4.c */ #include<stdio.h> #include<stdlib.h> int a[10]; // グローバル変数 ( どの関数からもアクセス可 ) int main() int b[10]; // ローカル変数 ( この関数内からのみアクセス可 ) int *c; // 動的に確保する領域へのポインタ int i; printf("address of a = %p, size of a[i] = %d bytes n", a, (int)sizeof(a[0])); for (i=0; i<10; i++) printf("address of a[%d] = %p n", i, &a[i]); printf("address of b = %p, size of b[i] = %d bytes n", b, (int)sizeof(b[0])); for (i=0; i<10; i++) printf("address of b[%d] = %p n", i, &b[i]); c = (int *)malloc(10*sizeof(*c)); // ヒープにメモリを確保 printf("address of c = %p, size of c[i] = %d bytes n", c, (int)sizeof(c[0])); for (i=0; i<10; i++) printf("address of c[%d] = %p n", i, &c[i]); printf("address of &a = %p, sizeof(&a) = %d bytes n", &a, (int)sizeof(&a)); printf("address of &b = %p, sizeof(&b) = %d bytes n", &b, (int)sizeof(&b)); printf("address of &c = %p, sizeof(&c) = %d bytes n", &c, (int)sizeof(&c)); free(c); return 0; 5

実行例 %./a.out Address of a = 0x601060, size of a[i] = 4 bytes Address of a[0] = 0x601060 Address of a[1] = 0x601064 Address of b = 0x7fff0347a1a0, size of b[i] = 4 bytes Address of b[0] = 0x7fff0347a1a0 Address of b[1] = 0x7fff0347a1a4 Address of c = 0x143d010, size of c[i] = 4 bytes Address of c[0] = 0x143d010 Address of c[1] = 0x143d014 Address of &a = 0x601060, sizeof(&a) = 8 bytes Address of &b = 0x7fff0347a1a0, sizeof(&b) = 8 bytes Address of &c = 0x7fff0347a198, sizeof(&c) = 8 bytes 実行中に確保される領域 ( サイズ不変 ) 0x7fff0347a1a0 0x7fff0347a198 実行中に確保される領域 ( サイズ可変 ) 0x143d010 実行前に確保される領域 ( サイズ不変 ) 0x601060 b[1] b[0] &c c[1] c[0] a[1] a[0] 6

配列を関数の引数にする #include<stdio.h> double sum(int n, double A[]) // 配列の長さは与えない ( 与えても無意味 ) // double *A でも同じ int i, x; x = 0; for (i=0; i<n; i++) x += A[i]; // x = x + A[i] の意味 return x; int main() double x; double B[3] = 1.0, 2.0, 3.0; x = sum(3, B); printf( x = %lf n,x); return 0; 7

関数でスカラー値以外を返したい場合 #include<stdio.h> int main() double x; int i; double B[3] = 1.0, 2.0, 3.0; double A[3]; for (i=0; i<3; i++) A[i] = -B[i]; for (i=0; i<3; i++) printf( %lf n, A[i]); return 0; 8

関数でスカラー値以外を返したい場合 #include<stdio.h> void invert(int n, double X[], double Y[]) // void は値を返さない関数の意味 int i; for (i=0; i<n; i++) Y[i] = -X[i]; int main() double x; double B[3] = 1.0, 2.0, 3.0; double A[3]; invert(3, B, A); for (i=0; i<3; i++) printf( %lf n, A[i]); return 0; 9

引数の値渡しと参照渡し 値渡し (call by value) 値をコピーしてサブルーチンに渡す サブルーチン内で値を変更しても元の値は変化しない 参照渡し (call by reference) 変数へのポインタをサブルーチンに渡す サブルーチン内で値を変更すると, 元の値も変化する C 言語は値渡し,Fortranは参照渡し C 言語で参照渡しをするときはポインタを引数にする 配列は参照渡しになっている 10

#include <stdio.h> #include <stdlib.h> void sub_value(int x) x = x + 1; printf("sub_value: x = %d n", x); void sub_reference(int x[]) x[0] = x[0] + 1; printf("sub_reference: x[0] = %d n", x[0]); void main(void) int x, y[1]; x = 1; y[0] = 1; printf("main: x = %d n", x); sub_value(x); printf("main: x = %d n", x); printf( main: y[0] = %d n, y[0]); 実行結果 main: x = 1 sub_value: x = 2 main: x = 1 main: y[0] = 1 sub_reference: x[0] = 2 main: y[0] = 2 sub_reference(y); // [] は付けない値ではなく y のポインタを渡している printf("main: y[0] = %d n", y[0]); 11

関数呼び出し #include <stdio.h> #include <stdlib.h> void sub_value(int x) x = x + 1; printf("sub_value: x = %d n", x); void main(void) int x; x = 1; printf("main: x = %d n", x); sub_value(x); printf("main: x = %d n", x); 実行結果 main: x = 1 sub_value: x = 2 main: x = 1 12

引数がポインタの場合 x は整数変数へのポインタ void sub_reference(int *x) *x = *x + 1; ポインタの中身を参照 printf("sub_reference: x = %d n", *x); void main(void) int y; y = 1; printf("main: y = %d n", y); yのアドレス sub_reference(&y); printf("main: y = %d n", y); 実行結果 main: y = 1 sub_reference: x = 2 main: y = 2 13

引数が配列の場合 配列は参照渡しになる void sub_reference(int x[]) x[0] = x[0] + 1; printf("sub_reference: x = %d n", x[0]); void main(void) int y[1]; y[0] = 1; printf("main: y = %d n", y[0]); sub_reference(y); printf("main: y = %d n", y[0]); 実は int *x と書いても同じ 実行結果 main: y = 1 sub_reference: x = 2 main: y = 2 14

struct ( 構造体 )1 複数の変数をまとめたもの struct matrix int n, m; // 行数, 列数 double **A; // 行列の中身 ; 15

struct ( 構造体 )2 typedef で構造体に名前をつけると便利 typedef struct int n, m; // 行数, 列数 double **A; // 行列の中身 matrix; matrix *X, *Y; // 行列の構造体へのポインタの宣言 X = malloc(sizeof(matrix)); // 構造体を格納するメモリを確保 X-> n = 3; X->m = 2; // 行数, 列数を構造体に書き込む 16

struct ( 構造体 )3 注意 : ポインタの代入では中身は複製されない int main() matrix *X, *Y; X = malloc(sizeof(matrix)); X->n = 3; Y = X; // ポインタの代入 Y->n = 4; 実行結果 X->n = 4 Y->n = 4 printf( X->n = %d n", X->n); printf( Y->n = %d n", Y->n); int main() matrix *X, *Y; X = malloc(sizeof(matrix)); X->n = 3; Y = malloc(sizeof(matrix)); // 新しい領域の確保 Y->n = 4; printf( X->n = %d n", X->n); printf( Y->n = %d n", Y->n); 実行結果 X->n = 3 Y->n = 4 17

struct ( 構造体 )4 関数の返り値を構造体へのポインタにする matrix *create_matrix(int n, int m) // 新しい零行列を作る関数 int i, j; matrix *X; X = malloc(sizeof(matrix)); // 構造体を格納するメモリを確保 X-> n = n; X->m = m; // 行数, 列数を構造体に代入 X->A = malloc(n*sizeof(double *)); // 行ベクトルの配列のメモリを確保して構造体に代入 // ここで列ベクトルのメモリを確保 for (i=0; i<n; i++) for (j=0; j<m; j++) X->A[i][j] = 0.0; // 値を初期化 return X; int main() matrix *A; A = create_matrix(3, 2); 18

第 3 回課題 : 2 つの行列の積を計算するプログラム 入力行列は標準入力から与えられる 1 行目は行列の行数と列数 1 つ目の行列のデータの直後に 2 つ目の行列のデータが来る 標準入力から続けて読めばいい 結果は標準出力に 入力と同じ形式 積を計算できない場合は 0 行 0 列の行列を出力する 出力は 0 0 の 1 行だけ 行列の形式 2 3 // 行数, 列数 1.0 2.0 3.0 // 1 行目 4.0 5.0 6.0 // 2 行目 main 関数の最後は return 0; をつけておく 提出するソースコードの中に, 学生証番号, 氏名, メールアドレスをコメントとして書いておく 締切 : 2017 年 4 月 25 日 ( 火 ) 17:35 ( 演習終了時 ) http://133.11.136.29/domjudge/ 19

ヒント : 以下の関数を順番に作っていけばいい matrix *create_matrix(int n, int m) n 行 m 列の零行列のメモリを確保する matrix *read_matrix() 標準入力から行列のデータを読み, 新しく行列を作る 行列のメモリはこの関数内で確保する void print_matrix(matrix *A) 行列を指定された形式で標準出力に書く matrix *product(matrix *A, matrix *B) 行列積を求め, 新しい行列を作る void free_matrix(matrix *X) 行列のメモリを開放する ( 作らなくても動くが ) 20

Windows 10 を使いたい人は Bash on Windows を入れる bash を起動し,make, gcc, gdb を入れる sudo apt-get install gcc sudo apt-get install make sudo apt-get install gdb valgrind を入れる 参考 http://blog.wagavulin.jp/entry/2016/08/30/230429 21