アルゴリズムとデータ構造 補足資料5-2 「サンプルプログラムsetop.c」

Slides:



Advertisements
Similar presentations
配列の宣言 配列要素の初期値 配列の上限 メモリ領域 多次元配列 配列の応用
Advertisements

15.1 文字列処理の基本 15.2 文字列処理用ライブラリ関数
プログラミング入門2 第4回 配列 for文 変数宣言 初期化
情報基礎演習B 後半第5回 担当 岩村 TA 谷本君.
数理情報工学演習第一C プログラミング演習 (第3回 ) 2014/04/21
配列(2) 第10回[平成15年6月26日(木)]:PN03-10.ppt 今日の内容 1 素数を求める(教科書の例):復習
データ構造とアルゴリズム 第10回 mallocとfree
プログラミング入門2 第10回 構造体 情報工学科 篠埜 功.
基礎プログラミングおよび演習 第9回
プログラミング演習(2組) 第12回
アルゴリズムとデータ構造 補足資料13-4 「2分探索木の追加・削除(ダイジェスト)」
情報処理Ⅱ 2005年12月9日(金).
第8回 プログラミングⅡ 第8回
理由:文字数より要素数の多い配列を用いた時に,文字列の最後を示すため
理由:文字数より要素数の多い配列を用いた時に,文字列の最後を示すため
アルゴリズムとデータ構造 補足資料7-3 「単純選択ソートselsort.c」
アルゴリズムとデータ構造 補足資料4-2 「線形探索」
アルゴリズムとデータ構造 補足資料6-3 「サンプルプログラムcat3.c」
第4回放送授業.
アルゴリズムとデータ構造 補足資料10-2 「nクイーン」
精密工学科プログラミング基礎Ⅱ 第3回資料 今回の授業で習得してほしいこと: 2次元配列の使い方 (前回の1次元配列の復習もします.)
C言語講座 第3回 ポインタ、配列.
プログラミング2 関数
関数とポインタ 値呼び出しと参照呼び出し swapのいろいろ 関数引数 数値積分
関数と配列とポインタ 1次元配列 2次元配列 配列を使って結果を返す 演習問題
プログラミング論 II 2008年10月30日 文字列
アルゴリズムとデータ構造 補足資料11-1 「mallocとfree」
第13章 文字の取り扱い方 13.1 文字と文字型変数 13.2 文字列 13.3 文字型配列への文字列の代入
第13章 文字の取り扱い方 13.1 文字と文字型関数 13.2 文字列 13.3 文字型配列への文字列の代入
第7回 プログラミングⅡ 第7回
復習 前回の関数のまとめ(1) 関数はmain()関数または他の関数から呼び出されて実行される.
プログラミング言語論 第五回 理工学部 情報システム工学科 新田直也.
アルゴリズムとデータ構造 補足資料4-1 「メモリと配列」
アルゴリズムとデータ構造 補足資料5-1 「メモリとポインタ」
高度プログラミング演習 (08).
地域情報学 C言語プログラミング 第5回 ポインタ、関数、ファイル入出力 2017年11月17日
アルゴリズムとデータ構造 補足資料6-2 「サンプルプログラムcat2.c」
復習 2次元配列 4列 j = 0 j = 1 j = 2 j = 3 i = 0 i = 1 i = 2 3行
プログラミング基礎B 文字列の扱い.
配列変数とポインタ 静的確保と動的確保 ポインタ配列 2次元配列 時間計測 第1回レポートの課題
メモリとメモリアドレス, ポインタ変数,関数へのポインタ渡し
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
プログラミング言語論 第六回 理工学部 情報システム工学科 新田直也.
IF文 START もしも宝くじが当たったら 就職活動する 就職活動しない YES END NO.
プログラミング入門2 第6回 関数 情報工学科 篠埜 功.
ポインタとポインタを用いた関数定義.
第13章 文字の取り扱い方 13.1 文字と文字型変数 13.2 文字列 13.3 文字型配列への文字列の代入
情報基礎演習B 後半第2回 担当 岩村 TA 谷本君.
第13回 ポインタ 1 1.
アルゴリズムとプログラミング (Algorithms and Programming)
アルゴリズムとデータ構造1 2009年6月15日
アルゴリズムとデータ構造 補足資料11-3 「線形リストのオペレータ」
第5回 プログラミングⅡ 第5回
オブジェクト指向言語論 第五回 知能情報学部 新田直也.
プログラミング入門2 第5回 配列 for文 変数宣言 初期化
アルゴリズムとデータ構造 補足資料7-1 「メモリでの『構造体の配列』」
アルゴリズムとデータ構造 補足資料6-1 「サンプルプログラムcat1.c」
アルゴリズムとデータ構造 2010年6月17日
アルゴリズムとデータ構造 補足資料5-3 「サンプルプログラムstrcat.c」
プログラミング入門2 第6回 関数 情報工学科 篠埜 功.
2005年度 データ構造とアルゴリズム 第2回 「C言語の復習:配列」
データ構造と アルゴリズム 第四回 知能情報学部 新田直也.
オブジェクト指向言語論 第三回 知能情報学部 新田直也.
15.1 文字列処理の基本 15.2 文字列処理用ライブラリ関数
プログラミング入門2 第5回 配列 変数宣言、初期化について
7.集合 7.1 集合とは [集合と要素] 関東の都道府県 群馬県 栃木県 要素 埼玉県 茨城県 東京都 千葉県 神奈川県
モバイルプログラミング第3回 Cプログラミングの基礎( 2 )
プログラミング演習I 補講用課題
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
= 55 課題6-1 #define _CRT_SECURE_NO_WARNINGS
Presentation transcript:

アルゴリズムとデータ構造 補足資料5-2 「サンプルプログラムsetop.c」 横浜国立大学 理工学部 数物・電子情報系学科 富井尚志

集合の表現 A = { 1, 2, 4, 5} 表現方法1:ビット列の位置で表す 表現方法2:配列に代入する 位置=要素 その位置のビットが1(True)→その要素が集合Aに存在する その位置のビットが0(False)→その要素は集合Aには存在しない 位置:要素 12345678 ビット   11011000                → 1101100 ≡ A = { 1, 2, 4, 5} とみなす 表現方法2:配列に代入する 添え字は特に意味を持たない 要素がこれ以上存在しないこと(終わり)を示す必要がある A[N]={1,2,4,5,-1} 「表現」=「みなす」(データ構造を定義した人=使う人、が決める) どちらの方法がよい、という議論はこの際しない。

サンプルプログラム: setop.c 集合の印刷 (一部抜粋) 配列名=配列へのポインタ に注目 集合の印刷 (一部抜粋) 配列名=配列へのポインタ に注目 関数printsetからは、main関数のブロック内だけで有効な 配列変数s[MAX]にポインタを使って参照することができる。 printsetの仮引数aは、int型配列への「ポインタ」変数。 printset内では、配列aとして扱う(配列sを参照する)ことができる。 配列sの実体は、main関数にある。

/. アルゴリズムとデータ構造 サンプルプログラム setop /**************************************************************** アルゴリズムとデータ構造 サンプルプログラム setop.c <<集合演算>> copyright (c) 1995,96,97 T.Mori <mori@forest.dnj.ynu.ac.jp> ****************************************************************/ #include <stdio.h> #define MAX 100 /* MAX は 配列の最大値要素数 */ #define EOSET -1 /* 集合の終りを表すマーク */ #define NOTMEMBER -2 /* 集合の要素がないことを表すマーク */ #define TRUE 1 /* 真 */ #define FALSE 0 /* 偽 */ void rmdup(int a[ ]); void printset(int a[ ]); void set_intersec(int a[ ],int b[ ], int c[ ]); void set_union(int a[ ],int b[ ], int c[ ]); void set_difference(int a[ ], int b[ ], int c[ ]); main() { int s[MAX] = {3,4,2,6,2,9,9,9,1,5,2,9,6,8,6,EOSET}; int t[MAX] = {1,2,3,4, 7,8,9,10,EOSET}; int u[MAX] = {1, 3,4,5,6,7, 9, EOSET}; int v[MAX]; printf("s[]: "); printset(s); /* 配列の名前だけを指定すると配列自身を指定したことになる. * 正確にいうと,配列が配置されている記憶領域の先頭の番地 * を表す. */ /* 略 */ return 0; } /* 集合の印刷 */ void printset(int a[]) { int i; for (i = 0; a[i] != EOSET; i++) { printf("%d ",a[i]); } printf("\n");

printf(“a[0]=%d, a[1]=%d\n”, a[0], a[1]); } s[3] 0x 40ea 0800 (s+3) a アドレス(32bit) 中身(1記憶単位は8bit) … 0x 40ea 0800 0000 0000 0x 40ea 0801 0x 40ea 0802 0x 40ea 0803 0000 0011 0x 40ea 0804 0x 40ea 0805 0x 40ea 0806 0x 40ea 0807 0000 0100 0x 40ea 0808 0x 40ea 0809 0x 40ea 080a 0x 40ea 080b 0000 0010 0x 40ea 080c 0x 40ea 080d 0x 40ea 080e 0x 40ea 080f 0000 0110 0x 40ea 0810 int s[100]; … f(s); s = 0x 40ea 0800 s s[0] s[0] s[1] s[2] … s[15] a[99] 3 4 2 EOSET (s+1) s[1] 配列sの実体はメモリの中に、 アドレスを伴なって存在する。 配列名sは、sの先頭アドレスを    示す。 (s+2) s[2] void f(int a[]) { printf(“a[0]=%d, a[1]=%d\n”, a[0], a[1]); } s[3] 0x 40ea 0800 (s+3) a 3, 4 と表示される: 関数fからは、aの名前で実体を参照する。 s[4] (s+4)

void printset( int a[] ) return 0; int main( void) 変数 int s[MAX] s = 0x 40ea 0800 s[0] s[1] s[2] … s[15] a[99] 3 4 2 EOSET printf("s[]: "); printset(s); void printset( int a[] ) return 0; 仮引数 int a[] 変数 int i for (i = 0; a[i] != EOSET; i++) { printf("%d ",a[i]); } printf("\n"); 戻り値なし(void)

int main( void) 変数 int s[MAX] s = 0x 40ea 0800 s[0] s[1] s[2] … s[15] 3 4 2 EOSET printf("s[]: "); printset(s); return 0; s[]:

int main( void) 変数 int s[MAX] s = 0x 40ea 0800 s[0] s[1] s[2] … s[15] 3 4 2 EOSET printf("s[]: "); printset(s); return 0; s[]:

void printset( int a[] ) return 0; int main( void) 変数 int s[MAX] s = 0x 40ea 0800 s[0] s[1] s[2] … s[15] a[99] 3 4 2 EOSET printf("s[]: "); printset(s); printset(40ea0800) void printset( int a[] ) return 0; 仮引数 int a[] 40ea0800 変数 int i for (i = 0; a[i] != EOSET; i++) { printf("%d ",a[i]); } printf("\n"); s[]: 戻り値なし(void)

void printset( int a[] ) return 0; int main( void) 変数 int s[MAX] s = 0x 40ea 0800 s[0] s[1] s[2] … s[15] a[99] 3 4 2 EOSET 値渡しによる 関数呼び出し Call by Value printf("s[]: "); printset(s); printset(40ea0800) void printset( int a[] ) return 0; 仮引数 int a[] 40ea0800 ポインタによる参照 Reference 変数 int i 参照渡しによる 関数呼び出しに相当 Call by Reference for (i = 0; a[i] != EOSET; i++) { printf("%d ",a[i]); } printf("\n"); s[]: 戻り値なし(void)

void printset( int a[] ) return 0; int main( void) 変数 int s[MAX] s = 0x 40ea 0800 s[0] s[1] s[2] … s[15] a[99] 3 4 2 EOSET printf("s[]: "); printset(s); printset(40ea0800) void printset( int a[] ) return 0; 仮引数 int a[] 40ea0800 変数 int i for (i = 0; a[i] != EOSET; i++) { printf("%d ",a[i]); } printf("\n"); s[]: 戻り値なし(void)

void printset( int a[] ) return 0; int main( void) 変数 int s[MAX] s = 0x 40ea 0800 s[0] s[1] s[2] … s[15] a[99] 3 4 2 EOSET printf("s[]: "); printset(s); printset(40ea0800) void printset( int a[] ) return 0; 仮引数 int a[] 40ea0800 変数 int i a[0] for (i = 0; a[i] != EOSET; i++) { printf("%d ",a[i]); } printf("\n"); s[]: 戻り値なし(void)

void printset( int a[] ) return 0; int main( void) 変数 int s[MAX] s = 0x 40ea 0800 s[0] s[1] s[2] … s[15] a[99] 3 4 2 EOSET printf("s[]: "); printset(s); printset(40ea0800) void printset( int a[] ) return 0; 仮引数 int a[] 40ea0800 変数 int i for (i = 0; a[i] != EOSET; i++) { printf("%d ",a[i]); } printf("\n"); a[0] s[]: 3 戻り値なし(void)

void printset( int a[] ) return 0; int main( void) 変数 int s[MAX] s = 0x 40ea 0800 s[0] s[1] s[2] … s[15] a[99] 3 4 2 EOSET printf("s[]: "); printset(s); printset(40ea0800) void printset( int a[] ) return 0; 仮引数 int a[] 40ea0800 変数 int i 1 for (i = 0; a[i] != EOSET; i++) { printf("%d ",a[i]); } printf("\n"); s[]: 3 戻り値なし(void)

void printset( int a[] ) return 0; int main( void) 変数 int s[MAX] s = 0x 40ea 0800 s[0] s[1] s[2] … s[15] a[99] 3 4 2 EOSET printf("s[]: "); printset(s); printset(40ea0800) void printset( int a[] ) return 0; 仮引数 int a[] 40ea0800 変数 int i 1 a[1] for (i = 0; a[i] != EOSET; i++) { printf("%d ",a[i]); } printf("\n"); s[]: 3 戻り値なし(void)

void printset( int a[] ) return 0; int main( void) 変数 int s[MAX] s = 0x 40ea 0800 s[0] s[1] s[2] … s[15] a[99] 3 4 2 EOSET printf("s[]: "); printset(s); printset(40ea0800) void printset( int a[] ) return 0; 仮引数 int a[] 40ea0800 変数 int i 1 a[1] for (i = 0; a[i] != EOSET; i++) { printf("%d ",a[i]); } printf("\n"); s[]: 3 4 戻り値なし(void)

サンプルプログラム: setop.c 集合の印刷 (一部抜粋) 配列名=配列へのポインタ に注目 集合の印刷 (一部抜粋) 配列名=配列へのポインタ に注目 関数printsetからは、main関数のブロック内だけで有効な 配列変数s[MAX]にポインタを使って参照することができる。 printsetの仮引数aは、int型配列への「ポインタ」変数。 printset内では、配列aとして扱う(配列sを参照する)ことができる。 配列sの実体は、main関数にある。

サンプルプログラム: setop.c 重複除去のアルゴリズム (一部抜粋) 配列名=配列へのポインタ に注目 重複除去のアルゴリズム (一部抜粋) 配列名=配列へのポインタ に注目 関数rmdupでは、二つの添え字 i と j を使って 配列aの2か所を参照する。 rmdupからは、配列名aによって配列sを参照している。 →main関数内のsの内容が書き換えられる。

/. アルゴリズムとデータ構造 サンプルプログラム setop /**************************************************************** アルゴリズムとデータ構造 サンプルプログラム setop.c <<集合演算>> copyright (c) 1995,96,97 T.Mori <mori@forest.dnj.ynu.ac.jp> ****************************************************************/ #include <stdio.h> #define MAX 100 /* MAX は 配列の最大値要素数 */ #define EOSET -1 /* 集合の終りを表すマーク */ #define NOTMEMBER -2 /* 集合の要素がないことを表すマーク */ #define TRUE 1 /* 真 */ #define FALSE 0 /* 偽 */ void rmdup(int a[ ]); void printset(int a[ ]); void set_intersec(int a[ ],int b[ ], int c[ ]); void set_union(int a[ ],int b[ ], int c[ ]); void set_difference(int a[ ], int b[ ], int c[ ]); main() { int s[MAX] = {3,4,2,6,2,9,9,9,1,5,2,9,6,8,6,EOSET}; int t[MAX] = {1,2,3,4, 7,8,9,10,EOSET}; int u[MAX] = {1, 3,4,5,6,7, 9, EOSET}; int v[MAX]; /* 略 */ /* 重複除去 */ printf("rmdup(s)\n"); rmdup(s); printf("s[]: "); printset(s); return 0; } /* 重複を除去する関数 */ void rmdup(int a[]) { int i,j,d; /* 重複する要素にマークをつける */ for(i=0; a[i] != EOSET; i++) for(j=i+1; a[j] != EOSET; j++) if (a[j] == a[i]) a[j] = NOTMEMBER; /* マークのついた要素をつめるように配列を作り直す */ d = 0; if (a[i] == NOTMEMBER) d++; /* 要素の移動距離を1だけ増やす */ else { if (d > 0) a[i-d] = a[i]; /* 距離 d だけ要素を前方に移動 */ } a[i-d] = a[i]; /* 配列の最後のマークも移動 */

int main( void) void rmdup( int a[] ) 変数 int s[MAX] s = 0x 40ea 0800 … 3 4 2 6 9 変数 int i 変数 int j printf("rmdup(s)\n"); rmdup(s); printf("s[]: "); printset(s); 変数 int d for(i=0; a[i] != EOSET; i++) for(j=i+1; a[j] != EOSET; j++) if (a[j] == a[i]) a[j] = NOTMEMBER; d = 0; if (a[i] == NOTMEMBER) d++; else { if (d > 0) a[i-d] = a[i]; } return 0; 戻り値なし(void)

int main( void) 変数 int s[MAX] s = 0x 40ea 0800 s[0] s[1] s[2] s[3] … 3 4 2 6 9 printf("rmdup(s)\n"); rmdup(s); printf("s[]: "); printset(s); return 0; rmdup(s)

int main( void) 変数 int s[MAX] s = 0x 40ea 0800 s[0] s[1] s[2] s[3] … 3 4 2 6 9 printf("rmdup(s)\n"); rmdup(s); printf("s[]: "); printset(s); return 0; rmdup(s)

int main( void) void rmdup( int a[] ) 変数 int s[MAX] s = 0x 40ea 0800 … 3 4 2 6 9 rmdup(40ea0800) 変数 int i 変数 int j printf("rmdup(s)\n"); rmdup(s); printf("s[]: "); printset(s); 変数 int d for(i=0; a[i] != EOSET; i++) for(j=i+1; a[j] != EOSET; j++) if (a[j] == a[i]) a[j] = NOTMEMBER; d = 0; if (a[i] == NOTMEMBER) d++; else { if (d > 0) a[i-d] = a[i]; } return 0; rmdup(s) 戻り値なし(void)

rmdupからは、配列名aによって配列sを参照している: 配列aだと思えばよい。 仮引数 int a[] a[0] a[1] a[2] void rmdup( int a[] ) rmdupからは、配列名aによって配列sを参照している: 配列aだと思えばよい。 仮引数 int a[] 40ea0800 a[0] a[1] a[2] a[3] a[4] a[5] … 3 4 2 6 9 変数 int i 変数 int j 変数 int d for(i=0; a[i] != EOSET; i++) for(j=i+1; a[j] != EOSET; j++) if (a[j] == a[i]) a[j] = NOTMEMBER; d = 0; if (a[i] == NOTMEMBER) d++; else { if (d > 0) a[i-d] = a[i]; } rmdup(s) 戻り値なし(void)

i = a[0] a[1] a[2] a[3] a[4] a[5] … 3 4 2 6 9 a[j] == a[i] ? j = 1

i = a[0] a[1] a[2] a[3] a[4] a[5] … 3 4 2 6 9 a[j] == a[i] ? j = 2

i = a[0] a[1] a[2] a[3] a[4] a[5] … 3 4 2 6 9 a[j] == a[i] ? j = 3

i = a[0] a[1] a[2] a[3] a[4] a[5] … 3 4 2 6 9 a[j] == a[i] ? j = … a[j] == EOSET までループ(内側のループ)

i = 1 iに1を追加(外側のループ) a[0] a[1] a[2] a[3] a[4] a[5] … 3 4 2 6 9 a[j] == a[i] ? j = 2

i = 1 a[0] a[1] a[2] a[3] a[4] a[5] … 3 4 2 6 9 a[j] == a[i] ? j = 3

i = 1 a[0] a[1] a[2] a[3] a[4] a[5] … 3 4 2 6 9 a[j] == a[i] ? j = … a[j] == EOSET までループ(内側のループ)

i = 2 iに1を追加(外側のループ) a[0] a[1] a[2] a[3] a[4] a[5] … 3 4 2 6 9 a[j] == a[i] ? j = 3

i = 2 a[0] a[1] a[2] a[3] a[4] a[5] … 3 4 2 6 9 a[j] == a[i] ビンゴ! j = 4

i = 2 a[0] a[1] a[2] a[3] a[4] a[5] … 3 4 2 6 9 a[j] == a[i] ビンゴ! j = NOT NUMBER 9 a[j] == a[i] ビンゴ! j = 4

a[j] == EOSET までループ(内側のループ) i = 2 a[0] a[1] a[2] a[3] a[4] a[5] … 3 4 2 6 NOT NUMBER 9 a[j] == a[i] ? j = … a[j] == EOSET までループ(内側のループ)

a[i] == EOSET までループ(外側のループ) a[0] a[1] a[2] a[3] a[4] a[5] … 6 NOT NUMBER 9 a[j] == a[i] ? j = …

i = a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] … 3 4 2 6 9 1 d = a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] … 3 4 2 6 NOT NUMBER 9 1 d =

i = 1 a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] … 3 4 2 6 9 1 d = NOT NUMBER 9 1 d =

i = 2 a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] … 3 4 2 6 9 1 d = NOT NUMBER 9 1 d =

i = 3 a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] … 3 4 2 6 9 1 d = NOT NUMBER 9 1 d =

i = 4 a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] … 3 4 2 6 9 1 d = 1 NOT NUMBER 9 1 d = 1

i = 5 a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] … 3 4 2 6 9 1 d = 1 NOT NUMBER 9 1 d = 1 a[ i-d] = a[i];

i = 5 a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] … 3 4 2 6 9 1 d = 1 NOT NUMBER 1 d = 1 a[ i-d] = a[i];

i = 6 a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] … 3 4 2 6 9 1 d = 2 NOT NUMBER 1 d = 2

i = 7 a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] … 3 4 2 6 9 1 d = 3 NOT NUMBER 1 d = 3

i = 8 a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] … 3 4 2 6 9 1 d = 3 NOT NUMBER 1 d = 3 a[ i-d] = a[i];

i = 8 a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] … 3 4 2 6 9 1 d = 3 NOT NUMBER d = 3 a[ i-d] = a[i];

i = 15 a[0] a[1] a[2] a[3] a[4] a[5] a[…] a[.] a[8] … 3 4 2 6 9 1 d = EOSET d = … a[ i-d] = a[i];

void rmdup( int a[] ) i = 15 仮引数 int a[] ` a[0] a[1] a[2] a[3] a[4] 40ea0800 a[0] a[1] a[2] a[3] a[4] a[5] a[…] 3 4 2 6 9 1 … 変数 int i 変数 int j 変数 int d for(i=0; a[i] != EOSET; i++) for(j=i+1; a[j] != EOSET; j++) if (a[j] == a[i]) a[j] = NOTMEMBER; d = 0; if (a[i] == NOTMEMBER) d++; else { if (d > 0) a[i-d] = a[i]; } 戻り値なし(void)

int main( void) void rmdup( int a[] ) i = 15 変数 int s[MAX] s = 0x 40ea 0800 仮引数 int a[] 40ea0800 a[0] a[1] a[2] a[3] a[4] a[5] a[…] 3 4 2 6 9 1 … s[0] s[1] s[2] s[3] s[4] s[5] … 3 4 2 6 9 変数 int i 変数 int j printf("rmdup(s)\n"); rmdup(s); printf("s[]: "); printset(s); 変数 int d for(i=0; a[i] != EOSET; i++) for(j=i+1; a[j] != EOSET; j++) if (a[j] == a[i]) a[j] = NOTMEMBER; d = 0; if (a[i] == NOTMEMBER) d++; else { if (d > 0) a[i-d] = a[i]; } return 0; return rmdup(s) 戻り値なし(void)

int main( void) 変数 int s[MAX] s = 0x 40ea 0800 s[0] s[1] s[2] s[3] … 3 4 2 6 9 s[0] s[1] s[2] s[3] s[4] s[5] s[…] 3 4 2 6 9 1 … printf("rmdup(s)\n"); rmdup(s); printf("s[]: "); printset(s); return 0; rmdup(s)の呼び出し前 s[0] s[1] s[2] s[3] s[4] s[5] … 3 4 2 6 9 rmdup(s) rmdup(s)から参照されて、 main関数内の自動配列変数sの中身が 変更された。

int main( void) 変数 int s[MAX] s = 0x 40ea 0800 s[0] s[1] s[2] s[3] 6 9 1 … s[0] s[1] s[2] s[3] s[4] s[5] … 3 4 2 6 9 printf("rmdup(s)\n"); rmdup(s); printf("s[]: "); printset(s); return 0; rmdup(s) s[]: 3 4 2 6 9 1 5 6 8