Act さんが書きました: ↑7年前
一応このプログラムで規定通りの動作をしてくれました。ただ、gcc -Wall を用いてコンパイルしたときに、「重複されて定義されています」という分がたくさん出てきてしまったのですが大丈夫なのでしょうか?
そのプログラムのソースファイルを a.c として、
Ubuntu(Linux)上でコンパイルすると、
コード:
$ gcc -Wall a.c
a.c: In function ‘main’:
a.c:62:9: warning: unused variable ‘fin’ [-Wunused-variable]
FILE *fin;
^
このように警告が出るだけです。
「重複されて定義されています」というエラーメッセージは出ません。
Windows上の Cygwin の gcc だと、
コード:
C:\tmp\C>gcc -Wall a.c
a.c: 関数 'main' 内:
a.c:62:9: 警告: 使用されない変数 'fin' です [-Wunused-variable]
FILE *fin;
^~~
やっぱり出ません。
「重複されて定義されています」というエラーメッセージが出るとしたら、
そこには、何が重複定義なのか書かれているはずです。
それらを無視しないでください。
さて、そのプログラムで何が定義されているかを見てみましょう。
コード:
$ gcc -c a.c
$ nm a.o
U __isoc99_fscanf
U __isoc99_scanf
U __stack_chk_fail
U fclose
U fopen
0000000000000220 T main
000000000000015e T nibuntansaku
U printf
U puts
0000000000000080 T seiretu
0000000000000000 T yomikomu
定義されているのは、main,nibuntansaku, seiretu, yomikomu の 4つです。
ここで思い当たることがあったので、次のようにコンパイルしてみました。
コード:
$ gcc -Wall a.c a.c
a.c: In function ‘main’:
a.c:62:9: warning: unused variable ‘fin’ [-Wunused-variable]
FILE *fin;
^
a.c: In function ‘main’:
a.c:62:9: warning: unused variable ‘fin’ [-Wunused-variable]
FILE *fin;
^
/tmp/ccCOc8yu.o: 関数 `yomikomu' 内:
a.c:(.text+0x0): `yomikomu' が重複して定義されています
/tmp/cc5hhJex.o:a.c:(.text+0x0): ここで最初に定義されています
/tmp/ccCOc8yu.o: 関数 `seiretu' 内:
a.c:(.text+0x80): `seiretu' が重複して定義されています
/tmp/cc5hhJex.o:a.c:(.text+0x80): ここで最初に定義されています
/tmp/ccCOc8yu.o: 関数 `nibuntansaku' 内:
a.c:(.text+0x15e): `nibuntansaku' が重複して定義されています
/tmp/cc5hhJex.o:a.c:(.text+0x15e): ここで最初に定義されています
/tmp/ccCOc8yu.o: 関数 `main' 内:
a.c:(.text+0x220): `main' が重複して定義されています
/tmp/cc5hhJex.o:a.c:(.text+0x220): ここで最初に定義されています
collect2: error: ld returned 1 exit status
a.c を 2個コンパイルしてできたオブジェクトファイルを
リンクすると、定義がぶつかります。
これではありませんか?
さて、プログラムの方ですが、関数 yoikomu が char を返しています。
fopen に失敗したとき、1を返していますが、これだと、ファイルに
データが 1個しかないとき、1を返すのと区別できません。
-1 を返すべきでしょう。
そして、main には、次のコードを追加したほうがよいでしょう。
if (n <= 0) { puts("データを読み込めません"); return 1; }
main の FILE *fin; は不要です。
関数定義の引数で、配列の要素数は不要です。
int yomikomu(int a[], char filename[])
さらに、これは
int yomikomu(int *a, char *filename)
と解釈されます。
どちらの書き方でも構いません。