请教!书本根本没教!求您的编程经验!喜欢C语言,感觉C语言比较努力,等考完试回家就看C语言实例^_^做题的时候
请教!书本根本没教!求您的编程经验!
喜欢C语言,感觉C语言比较努力,等考完试回家就看C语言实例^_^
做题的时候出了些课本没有的问题,一般自己不这样写,但考试题就这么蛋疼,没办法。
第一个问题,到底在后面的自增运算符(如i++),在什么时候才会完成自加?我觉得在逗号运算符,printif()的参数之类用自增是非常蛋疼的,如这个。
#include <stdio.h>
void main(int argc,char *argv[])
{
int m=5;
if(m++>5)
printf("%d\n",m);
else
printf("%d\n",m--);
}
答案是6。应该怎样理解呢?
还有这个
#include<stdio.h>
struct a
{
char name[10];
int age;
}aa[3]={{"abc",20},{"def",21},{"ghi",22}};
main()
{
struct a *paa=aa;
printf("%c%c%c",(*(paa+2)).name[0],(*paa++).name[1],(*(paa+1)).name[2]);
}
我理解的答案是gbi,答案(也是我的运行结果)却是gbf。说明第三个参数中paa仍指向aa[0],则paa+1指向aa[1]。为什么前面的自增还没起作用呢?
第二个问题:目前的编译器,printf的参数是从左到右求值的多,还是从右到左求值的多呢?我觉得我问这个问题很迂腐,但TMD选择题就提供两种求值的选项,选哪个好?
[解决办法]
#include <stdio.h>
void main(int argc,char *argv[])
{
int m=5;
if(m++>5)
printf("%d\n",m);
else
printf("%d\n",m--);
}
=>
#include <stdio.h>
void main(int argc,char *argv[])
{
int m=5;
if(m>5)
{
m+=1;
printf("%d\n",m);
}
else
{
m+=1;
printf("%d\n",m);
m-=1;
}
}
第二个问题不要关心,C标准没有定义。
在代码中不要使用没有明确定义的行为
[解决办法]其实这2个概念没有什么难的,只是有时候具体情况会比较复杂。。副作用就是能够改变原来的数据对象的,比如i++,比如i=10,这就改变了i原来的值,尽管这个改变是你希望的,但是还是叫副作用,顺序点就是在一个点之前,前面所有的副作用都会生效,比如","就是一个顺序点,在它之前比如有i++,那在“,”之后用的就是i自增后的值,还有完整表达式也是顺序点。。
当然还有蛮多复杂的情况,具体还要看编译器。。可以稍微参考下C primer plus 第五版的第五章,但是也没有讲很多。。
[解决办法]VC调试时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
(Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
提醒:
“学习用汇编语言写程序”
和
“VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)”
不是一回事!
不要迷信书、考题、老师、回帖;
要迷信CPU、编译器、调试器、运行结果。
并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。
任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实!
有人说一套做一套,你相信他说的还是相信他做的?
其实严格来说这个世界上古往今来所有人都是说一套做一套,不是吗?
不要写连自己也预测不了结果的代码!
对学习编程者的忠告:
眼过千遍不如手过一遍!
书看千行不如手敲一行!
手敲千行不如单步一行!
单步源代码千行不如单步对应汇编一行!