本節指出的錯誤不涉及指針(涉及指針類的錯誤將放在數組與指針關係中討論),為了熟悉一維數組,本節仍然不討論多維數組。
【例5.5】賦值錯誤的例子。
#include <stdio.h> int main ( ) { int i , a[5]={1 ,3 ,5 ,7 ,9} ,b[5] ; char ch="good !" ,st[6] ; b=a ; st=ch ; for (i=0 ;i<5 ;i++ ) printf ("%d " ,b[i] ); printf ("\n" ); printf (st ); printf ("\n" ); return 0 ; }
數組沒有賦值運算符「=」,必須一個一個元素的賦值。
正確的程序如下:
#include <stdio.h> int main () { int i , a[5]={1 ,3 ,5 ,7 ,9} ,b[5] ; char ch="good !" ,st[6] ; for (i=0 ;i<5 ;i++ ) b[i]=a[i] ; for (i=0 ;i<6 ;i++ ) st[i]=ch[i] ; for (i=0 ;i<5 ;i++ ) printf ("%d " ,b[i] ); printf ("\n" ); printf (st ); printf ("\n" ); return 0 ; }
【例5.6】下面的程序使用鍵盤賦值,程序是否有錯?
#include <stdio.h> int main () { int i , a[5] ; char ch[5] ; for (i=0 ;i<5 ;i++ ) scanf ("%d" ,&a+i ); for (i=0 ;i<5 ;i++ ) printf ("%d " ,*a+i ); printf ("\n" ); for (i=0 ;i<5 ;i++ ) scanf ("%c" ,ch+i ); ch[i]='\0' ; printf (ch ); printf ("\n" ); return 0 ; }
程序中對數組a的賦值不對,i=0時,語句
scanf ("%d" ,&a );
為第1個元素a[0]賦值。當i=1時,「&a+1」的含義是「&a」的地址值加1,而不是第2個元素a[1]的地址。a[1]的地址應該是「&a[1]」,使用語句
scanf ("%d" ,&a[i+1] );
才是正確的。還有一個正確的寫法,就是用地址循環。因為數組名就是數組存儲的首地址,所以a+1代表的是首地址移動到第2個元素存儲的首地址,也就是第2個元素的數組名。注意到a,&a和&a[0]的含義一樣,都是第1個元素a[0]的地址。「a+1」就代表a[1]的地址,與「&a[1]」等效,所以如下兩條語句都是正確的。
scanf ("%d" ,&a[i] ); scanf ("%d" ,a+i );
scanf要求的是存儲元素的首地址,所以上述兩條語句是等效的。
同理,printf輸出的是地址裡的內容。a存放的是第1個元素的首地址,*a是第1個元素的值。「*a+1」是數組第1個元素之值加1,顯然是不對的,應該是「*(a+1)」。「a+1」代表了首地址移動1個元素的地址,即第2個元素的首地址。下述兩條語句是等效的。
printf ("%d " ,* (a+i )); printf ("%d " ,a[i] );
修改後的程序如下:
#include <stdio.h> int main () { int i , a[5] ; char ch[5] ; for (i=0 ;i<5 ;i++ ) scanf ("%d" ,a+i ); // 等效scanf ("%d" ,&a[i] ); for (i=0 ;i<5 ;i++ ) printf ("%d " ,* (a+i )); // 等效printf ("%d " ,a[i] ); printf ("\n" ); for (i=0 ;i<5 ;i++ ) scanf ("%c" ,ch+i ); // 等效scanf ("%c" ,ch[i] ); ch[i]='\0' ; printf (ch ); printf ("\n" ); return 0 ; }
輸出結果如下:
1 3 5 7 9 1 3 5 7 9 abcde abcd
輸入字符,只能接收5個,但要存入一個結束符,所以如果輸入4個,則存入正確,如果輸入5個,最終只能存放4個字符。上述的字符輸入和輸出也證明了這一點。