初学C语言的人最容易犯的错误集锦(三)

错误3.1

从键盘输入三个字符串保存到char数组中:
int i,n=3;
char *name[3];
for(i=0;i<n;i++)
  scanf("%s",name[i]);这段代码有错吗?看起来好像没错,也可以编译通过,但是运行的时候我们输入要设置的字符会造成“程序内存访问冲突”之类的程序错误。为什么呢?
注意scanf第二个参数是待设置变量的指针,而不是变量的值,比如要将用户输入的数字保存到变量i中的话要使用 scanf("%s",&i),而不是scanf("%s",i),这也不需要强行记忆,因为所有需要“设置变量”的地方都要传递变量的地址,而所有需要“读取变量”的地方都要传递变量的名字。
name是一个char数组,所以name[i]表示name数组的第i个元素的值,因此要取name[i]的值,修正后的代码如下:
int i,n=3;
char *name[3];
for(i=0;i<n;i++)
  scanf("%s",&name[i]);  
 

错误3.2 曾经有同学在如鹏网的官方QQ群中提了下面的问题:
printf("%c%c",getchar(),getchar());
输入 "ab <回车>"
为什么显示为 b a?
这个问题比较复杂,要理解的话首先要理解函数调用中的“参数列表求值顺序”的概念。这个概念是所有编程语言都会涉及到的问题,并不局限于C语言,这也是一个“一通百通”的知识点,需要深刻理解。
假设有下面的一个函数f1:
void f1(int i1,int i2,int i3)
{
printf("i1=%d,i2=%d,i3=%d",i1,i2,i3);
}
在调用函数的时候,如果给函数传递的是普通的变量那么并不会体会到“参数列表求值顺序”的概念,比如代码段“f1(a,b,c)”的含义是“调用f1函数,并且给f1函数的参数1、参数2、参数3分别赋值为a、b、c三个变量”。那么如果是下面的代码呢:
int i=10;
f1(i++,i++,i++);
很多同学都认为上边的代码会打印出“i1=10,i2=11,i3=12”,但是运行以后你会发现与预想的完全相反:“i1=12,i2=11,i3=10”。这是和函数参数计算顺序(准确的讲应该叫“函数参数压栈顺序”)相关的,通俗的讲就是如果函数的参数不是简单的变量或者常量,而是需要进行计算的表达式、函数的时候,是按照从左到右还是从右到左的顺序计算函数的参数,C/C++的默认函数参数计算顺序是从右到左,也就是说对于“f1(i++,i++,i++)”来说会首先计算第三个参数、再计算第二个参数、再计算第一个参数,因此三个参数的值将会是“12、11、10”,这就不难解释貌似奇怪的执行结果了。
明白了这个道理,对于本文开始的例子出现的怪异行为也就不会奇怪了,因为输入的a被做为第二个getchar的返回值,b则被做为第一个getchar的返回值。
其实C/C++标准并没有规定函数参数计算顺序,不过主流的编译器都是从右至左的顺序。
关于这个问题可以参考更多资料:
http://www.pcppc.cn/kaifa/Cyuyan/kaifa_18355.html
http://yuyuan19830705.spaces.live.com/Blog/cns!5DD090CD225C426B!127.entry?wa=wsignin1.0
 

你可能感兴趣的:(编程,c,qq,ini,语言,编译器)