本节指出的错误不涉及指针(涉及指针类的错误将放在数组与指针关系中讨论),为了熟悉一维数组,本节仍然不讨论多维数组。
【例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 91 3 5 7 9abcdeabcd
输入字符,只能接收5个,但要存入一个结束符,所以如果输入4个,则存入正确,如果输入5个,最终只能存放4个字符。上述的字符输入和输出也证明了这一点。