配列変数とポインタ 静的確保と動的確保 ポインタ配列 2次元配列 時間計測 第1回レポートの課題

Slides:



Advertisements
Similar presentations
第 11 章 関数について 11.1 標準ライブラリ関数 11.2 関数呼び出しのオーバーヘッド 11.3 大域変数 11.4 プロトタイプ宣言 数学関数の自作.
Advertisements

1 例題 ex3b ( 配列 ) 科学科プログラミング. 2 例題 : ex3b  以下の 3 つについて例題を進める ステップ 1 :配列 ステップ 2 :最小と最大 ステップ 3 :文字型の配列.
オブジェクト指向言語・ オブジェクト指向言語演習 中間試験回答例. Jan. 12, 2005 情報処理技術基礎演習 II 2 オブジェクト指向言語 中間試験解説 1  (1) 円柱の体積(円柱の体積 = 底面の円の面積 x 高さ) を求めるプログラムを作成しなさい。ただし、出力結果は、入 力した底面の円の半径.
配列の宣言 配列要素の初期値 配列の上限 メモリ領域 多次元配列 配列の応用
15.1 文字列処理の基本 15.2 文字列処理用ライブラリ関数
情報基礎演習B 後半第5回 担当 岩村 TA 谷本君.
数理情報工学演習第一C プログラミング演習 (第3回 ) 2014/04/21
プログラミング入門2 第10回 動的な領域確保 情報工学科 篠埜 功.
配列(2) 第10回[平成15年6月26日(木)]:PN03-10.ppt 今日の内容 1 素数を求める(教科書の例):復習
データ構造とアルゴリズム 第10回 mallocとfree
システムプログラミング 第5回 情報工学科 篠埜 功 ヒアドキュメント レポート課題 main関数の引数 usageメッセージ
岩村雅一 知能情報工学演習I 第9回(C言語第3回) 岩村雅一
16.3 関数と構造体 構造体ポインタ 地底探査ゲーム
第14章 ファイル操作 (コマンドプロンプト版)
多重ループ 繰り返し構造:補足事項 第8回目 [6月8日、H.16(‘04)] 本日のメニュー 1)前回の課題について
多重ループ 繰り返し構造:補足事項 第8回目 [6月12日、H.15(‘03)] 本日のメニュー 1)前回の課題について
OSとコマンド OS:コンピュータを使うための基本プログラム コマンド:OS上で使用できる命令 OS本体であるカーネルの内部コマンド
Excelによる3-D/等高線グラフの描画 2変数関数の描画 Excel によるグレイスケールマップ風描画
12: コマンドライン引数 C プログラミング入門 総機1 (月1) Linux にログインし、以下の講義ページ を開いておくこと
第8回 プログラミングⅡ 第8回
理由:文字数より要素数の多い配列を用いた時に,文字列の最後を示すため
理由:文字数より要素数の多い配列を用いた時に,文字列の最後を示すため
第6章 2重ループ&配列 2重ループと配列をやります.
配列の扱い、探索 有効範囲と記憶域期間 第12回 [7月10日、H.15(‘03)] 今日のメニュー 1 前回の課題の復習
プログラミング演習Ⅰ 課題2 10進数と2進数 2回目.
第3回 配列,構造体,ポインタ ~ データ構造について学ぶための基礎~
精密工学科プログラミング基礎Ⅱ 第3回資料 今回の授業で習得してほしいこと: 2次元配列の使い方 (前回の1次元配列の復習もします.)
オセロを作るとします。 各マスの状態を保存するために64個の変数が必要です。 でも64個も変数を作るのはめんどくさいですよね。
C言語講座 第3回 ポインタ、配列.
プログラミング論 ファイル入出力
関数とポインタ 値呼び出しと参照呼び出し swapのいろいろ 関数引数 数値積分
関数と配列とポインタ 1次元配列 2次元配列 配列を使って結果を返す 演習問題
精密工学科プログラミング基礎 第10回資料 (12/18実施)
2005年度 データ構造とアルゴリズム 第3回 「C言語の復習:再帰的データ構造」
アルゴリズムとデータ構造 補足資料5-2 「サンプルプログラムsetop.c」
プログラミング入門2 第11回 情報工学科 篠埜 功.
第13章 文字の取り扱い方 13.1 文字と文字型変数 13.2 文字列 13.3 文字型配列への文字列の代入
プログラミング入門2 第11回 情報工学科 篠埜 功.
第7回 プログラミングⅡ 第7回
第14章 ファイル操作 (コマンドプロンプト版)
アルゴリズムとデータ構造 補足資料5-1 「メモリとポインタ」
プログラミング論 ファイル入出力
関数の再帰呼び出しとは ハノイの塔 リダイレクト レポート課題
岩村雅一 知能情報工学演習I 第9回(後半第3回) 岩村雅一
第14章 ファイル操作 14.1 ファイルへの書き込み 14.2 ファイルからの読み込み 14.3 ファイルへの追加書き込み
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
プログラミング言語論 第六回 理工学部 情報システム工学科 新田直也.
精密工学科プログラミング基礎Ⅱ 第5回資料 今回の授業で習得してほしいこと: 構造体 (教科書 91 ページ)
第14章 ファイル操作 14.1 ファイルへの書き込み 14.2 ファイルからの読み込み 14.3 ファイルへの追加書き込み
プログラミング基礎a 第6回 C言語によるプログラミング入門 配列と文字列(その2)
15.1 文字列処理の基本 15.2 文字列処理用ライブラリ関数
プログラミング 3 2 次元配列.
復習 Cにおけるループからの脱出と制御 break ループを強制終了する.if文と組み合わせて利用するのが一般的. continue
第13章 文字の取り扱い方 13.1 文字と文字型変数 13.2 文字列 13.3 文字型配列への文字列の代入
Excelによる3-D/等高線グラフの描画 2変数関数の描画 Excel によるグレイスケールマップ風描画
ネットワーク・プログラミング Cプログラミングの基礎.
プログラミング 4 文字列.
11: 動的メモリ確保 C プログラミング入門 基幹2 (月4) Linux にログインし、以下の講義ページ を開いておくこと
2005年度 データ構造とアルゴリズム 第2回 「C言語の復習:配列」
情報処理Ⅱ 2005年11月25日(金).
15.1 文字列処理の基本 15.2 文字列処理用ライブラリ関数
プログラミング入門2 第5回 配列 変数宣言、初期化について
第4回 配列.
第14章 ファイル操作 14.1 ファイルへの書き込み 14.2 ファイルからの読み込み 14.3 ファイルへの追加書き込み
第5回 配列.
プログラミング演習I 補講用課題
岩村雅一 知能情報工学演習I 第7回(後半第1回) 岩村雅一
12: コマンドライン引数 C プログラミング入門 基幹2 (月4) Linux にログインし、以下の講義ページ を開いておくこと
= 55 課題6-1 #define _CRT_SECURE_NO_WARNINGS
岩村雅一 知能情報工学演習I 第9回(C言語第3回) 岩村雅一
Presentation transcript:

配列変数とポインタ 静的確保と動的確保 ポインタ配列 2次元配列 時間計測 第1回レポートの課題 第9章 ポインタ 配列変数とポインタ 静的確保と動的確保 ポインタ配列 2次元配列 時間計測 第1回レポートの課題

ポインタ変数(ex_9_3_5.c) #include <stdio.h> #define PRINT(x,y,z) printf(#x"= %d, "#y"= %d, "#z"= %d\n",x,y,z); int main(void) { int x = 1, y = 100; int *p; PRINT(x,y,p); p = &x; PRINT(x,y,p); y = *p; PRINT(x,y,p); p = &y; PRINT(x,y,p); *p = 0; PRINT(x,y,p); PRINT(&x,&y,&p); return 0; } x=1, y=100, p=4199225 x=1, y=100, p=1245044 x=1, y=1, p=1245044 x=1, y=1, p=1245048 x=1, y=0, p=1245048 &x=1245044, &y=1245048, &p=1245052

ポインタ変数(ex9_3_5.c) int x = 1, y = 100; int *p; p = &x; y = *p; p = &y; 100 1 1245052 p 1245044 4199225 1245048

9.4 配列変数とポインタ (再掲) 配列(array)とは int a[5]={11,12,13,14,15}; 9.4 配列変数とポインタ (再掲) 配列(array)とは int a[5]={11,12,13,14,15}; ← プログラム例9.4.1 と宣言すると、メモリ上に右図のように並んだ int 型変数 5 個分の領域が確保され、その領域が a と名付けられる。 各々の配列要素には指定された値が入る。 配列要素 11 a[0] 12 a[1] 13 14 a[3] 15 a[2] a[4] 添字

9.4 配列変数とポインタ (再掲) int *a_p; a_p = &a[0]; C では、配列変数はポインタ変数 9.4 配列変数とポインタ (再掲) C では、配列変数はポインタ変数 を用いてアクセスすることが多い 11 1000 1004 1008 1012 1016 a[0] &a[0] は1000、 &a[1] は1004 12 a[1] 13 a[2] 14 int *a_p; a_p = &a[0]; a[3] 15 a[4] a_p は、整数型変数のアドレスが 入るポインタ型変数で(1行目)、 配列 a の先頭の要素の番地を 代入する(2行目) 1000 a_p

配列変数の正体 コンパイラは a[i] を *(a+i) と解釈 &a[i] = &(*(a+i)) = a+i 特に、 &a[0] = a 11 1000 1004 1008 1012 1016 a[0] 12 a[1] 13 配列 a の名前自体が配列の先頭要素の番地を表すポインタとみなせる a[2] 14 a[3] 15 ただし、a が a_p のようなポインタ変数として独立に存在するわけではない a[4] 実は、 a[i] = *(a+i) = *(i+a) = i[a] が成り立つ。→ ex9_4_1a.c

ポインタと配列変数の関係 ex9_4_1a.c #include <stdio.h> int main(void) { int i, a[]={11,12,13,14,15}; printf(" a[i]= "); for (i=0; i<5; i++) printf("%d ",a[i]); putchar('\n'); printf("*(a+i)= "); for (i=0; i<5; i++) printf("%d ",*(a+i)); putchar('\n'); printf(" i[a]= "); for (i=0; i<5; i++) printf("%d ",i[a]); putchar('\n'); printf("\n &a=%u, a=%u, *a=%d\n",&a, a, *a); } ex9_4_1a.c

みなしポインタaの中身(スタック領域のアドレス) 実行結果(静的確保) Z:\nyumon2>ex9_4_1a a[i]= 11 12 13 14 15 *(a+i)= 11 12 13 14 15 i[a]= 11 12 13 14 15 &a=1245036, a=1245036, *a=11 aが指し示す先のデータ = a[0] みなしポインタaのアドレス (スタック領域) みなしポインタaの中身(スタック領域のアドレス) a[0] a[1] 1245036 11 1245040 12 アドレスがループしており、配列名aはポインタ変数ではない

動的確保の場合のポインタと配列 ex9_4_1b.c #include <stdio.h> #define N 5 int main(int argc, char *argv[]) { int i, n=N, *a; if (argc > 1) sscanf(argv[1], "%d", &n); if ((a = (int *)calloc(n, sizeof(int))) == NULL) { perror("I can't allocate a[]."); abort(); } for (i=0; i<n; i++) a[i]=11+i; printf(" a[i]= "); for (i=0; i<n; i++) printf("%d ", a[i]); putchar('\n'); printf("\n &a=%u, a=%u, *a=%d\n",&a, a, *a); ex9_4_1b.c

ポインタ変数aの中身(ヒープ領域のアドレス) 実行結果(動的確保) Z:\nyumon2>ex9_4_1b a[i]= 11 12 13 14 15 &a=1245052, a=4260528, *a=11 aが指し示す先のデータ = a[0] ポインタ変数a のアドレス (スタック領域) ポインタ変数aの中身(ヒープ領域のアドレス) 1245052 4260528 4260532 4260528 a a[0] a[1] 11 動的確保した配列a[]の実体は ヒープ領域に確保 12

ポインタ配列 ポインタを要素に持つ配列 文字列配列や2次元配列で用いる int *a[N]; char *argv[] int *a[0],*a[1],...,*a[N-1]; char *argv[] コマンドラインの文字列配列 Z:\nyumon2>ex_9_4_1b 10 argv[0] = "ex_9_4_1b" argv[1] = "10"

2次元配列の静的確保(自動変数) ex6_7_2c.c スタック領域に確保 #include <stdio.h> #define N 4 int main(void) { int i, j, k=0; int a[N][N]; for (i = 0; i < N; i++) for (j = 0; j < N; j++) a[i][j] = ++k; printf("&a=%u, a=%u, *a=%u, **a=%d\n", &a, a, *a, **a); return 0; } ex6_7_2c.c スタック領域に確保

2次元配列の静的確保(静的変数) ex6_7_2d.c データ領域に確保 #include <stdio.h> #define N 4 int main(void) { int i, j, k=0; static int a[N][N]; for (i = 0; i < N; i++) for (j = 0; j < N; j++) a[i][j] = ++k; printf("&a=%u, a=%u, *a=%u, **a=%d\n", &a, a, *a, **a); return 0; } ex6_7_2d.c データ領域に確保

2次元配列の静的確保(大域変数) ex6_7_2e.c データ領域に確保 #include <stdio.h> #define N 4 int a[N][N]; int main(void) { int i, j, k=0; for (i = 0; i < N; i++) for (j = 0; j < N; j++) a[i][j] = ++k; printf("&a=%u, a=%u, *a=%u, **a=%d\n", &a, a, *a, **a); return 0; } ex6_7_2e.c データ領域に確保

実行結果(静的確保) Z:\nyumon2>ex6_7_2c &a=1310528, a=1310528, *a=1310528, **a=1 Z:\nyumon2>ex6_7_2d &a=4221348, a=4221348, *a=4221348, **a=1 Z:\nyumon2>ex6_7_2e &a=4221792, a=4221792, *a=4221792, **a=1 スタック領域 データ領域 (静的領域) データ領域 1310528 1 4221348 1 4221792 1 1310532 2 4221352 2 4221796 2

2次元配列の動的確保(1) ex6_7_2f.c #include <stdio.h> #include <stdlib.h> #define N 4 int main(void) { int i, j, k=0; int *a[N]; for (i = 0; i < N; i++) { a[i] = (int *)calloc(N, sizeof(int)); for (j = 0; j < N; j++) a[i][j] = ++k; } printf("&a=%u, a=%u, *a=%u, **a=%d\n", &a, a, *a, **a); return 0; ex6_7_2f.c スタック領域にポインタ配列 ヒープ領域に確保

2次元配列の動的確保(2) ex6_7_2g.c #include <stdio.h> #include <stdlib.h> #define N 4 int main(void) { int i, j, k=0; int **a; a = (int **)calloc(N, sizeof(int *)); for (i = 0; i < N; i++) { a[i] = (int *)calloc(N, sizeof(int)); for (j = 0; j < N; j++) a[i][j] = ++k; } printf("&a=%u, a=%u, *a=%u, **a=%d\n", &a, a, *a, **a); return 0; ex6_7_2g.c スタック領域にポインタのポインタ ヒープ領域に ポインタ配列 ヒープ領域に確保

2次元配列の動的確保(3) ex6_7_2h.c #include <stdio.h> #include <stdlib.h> #define N 4 #define IDX(i,j) (i)*N+(j) int main(void) { int i, k=0; int *a; a = (int *)calloc(N*N, sizeof(int)); for (i = 0; i < N*N; i++) a[i] = ++k; printf("&a=%u, a=%u, *a=%u, **a=%d\n", &a, a, *a, **a); printf("%d, %d, %d\n",a[IDX(1,1)],a[IDX(2,2)],a[IDX(3,3)]); return 0; } ex6_7_2h.c スタック領域にポインタ ヒープ領域に確保

実行結果(動的確保) スタック 1310576 a[0] 4260480 1310580 a[1] 4260448 Z:\nyumon2>ex6_7_2f &a=1310576, a=1310576, *a=4260480, **a=1 Z:\nyumon2>ex6_7_2g &a=1310588, a=4260480, *a=4260448, **a=1 Z:\nyumon2>ex6_7_2h &a=1310588, a=4260480, *a=1 6, 11, 16 ヒープ 4260480 **a 4260484 1 2 ヒープ スタック 4260448 **a 4260452 1 1310588 a 4260480 スタック 2 ヒープ 1310588 a 4260480 4260480 *a 4260484 1 4260480 *a 4260448 2

時間計測:ミリ秒単位(time2.c) 再掲 #include <stdio.h> #include <stdlib.h> #include <windows.h> #pragma comment(lib,"winmm.lib") int main(void) { int i, N=100000; int t1, t2; t1 = timeGetTime(); for (i=0; i<N; i++) printf(" %d", rand()%6 + 1); printf("\n"); t2 = timeGetTime(); printf("経過時間: %d msec\n", t2-t1); return 0; } ← 乱数用ヘッダファイル ← Windows用ヘッダファイル ← 音楽用Windowsライブラリ 計測開始 計測終了 実行時間

「エラトステネスの篩」改良版(prime2.c) 配列 a をデータ領域または動的に確保する(char 型にすると上限が4倍になる) 動的確保の場合、コマンドラインオプションで素数の上限 n を入力できるようにする (n-1000)から上の素数を(整数10桁で)表示 素数の個数を数えあげて表示 経過時間を計測して表示 n のデフォルト値は1億または10億とする 5

エラトステネスの篩(ふるい)改良版 t1 100,000,000 or 500,000,000 コマンドラインから n の入力 エラー処理つき配列 a[ ] 確保&初期化 ←callocで動的確保 j ← i+i i の倍数 を除く a[j] ← 1 !a[i] i=2,...,N/2  j≦N j ← j+i prime2 k ← 0 k ← k+1 !a[i] i=2,...,N  i の10桁出力 i > n-1000 後ろの素数を出力 素数の数 k の出力 t2 経過時間(t2-t1)の出力

第1回 レポート(必須) 課題:「エラトステネスの篩」改良版(prime2.c) 提出期限:2010年10月29日(金) 12:50 (コマンドライン入力&動的確保) 提出期限:2010年10月29日(金) 12:50 提出場所:ネットワーク実験室(1)の入口近くの箱 今回のレポートでは以下の項目をいれること。 学籍番号、氏名 課題名 ソースリスト 実行結果 感 想(5行以上) レポートのファイルは 保存しておくこと レポートサンプルを参照のこと

本日のパズル 次のプログラムは何が出力されるか? #define PRINT3(x,y,z) printf("%d\t%d\t%d\n",x,y,z) main() { int x, y, z; x = y = z = 1; ++x || ++y && ++z; PRINT3(x,y,z); ++x && ++y || ++z; PRINT3(x,y,z); ++x && ++y && ++z; PRINT3(x,y,z); } 1 2 3