65,209
社区成员
发帖
与我相关
我的任务
分享void main()
{
for (int i = 0 ; i < 10 ; i++)
{
int k;
// k++;
printf("%x\n",&k);
if (i == 0)
{
// k = 0;
k++;
}
else
{
k++;
}
printf("%d %x \n",k,&k);
}
getchar();
}第一个问题:你说:把k++打开,运行出错,原因是K没有初始化 这个是没有问题的。一个垃圾值(未初始化的局部变量),你读它根本没问题,输出他的地址也OK,只不过程序没意义。 一个局部变量一旦定义,在他的生存期内,他 的地址是不会变的。所以k地址不会变。 栈变量是系统分配的内存,你无法干预和改变。 问题是,k未初始化,他的值是垃圾值。你无法预测。所以你加加减减,输出什么的,都会看到是垃圾值。 还有,不要不定义放到循环里面,这样没错,但是不好。一个变量定义一次了,你使用完了又把它定义一遍,没理由这样做。 你可以放在for( int k ; ; ) 这里,或者for外面。
与printf无关,是因为vc调试器会插入调试代码(检查变量是否已经初始化),导致k++的时候报错。用release就没有问题。 局部变量的周期就是一个作用域内,在本例中,就是一次for循环,也就是每次for循环,否有一个新的k产生。之所以新生成的局部变量还会每次累加,是因为局部变量的分配地址的问题。编译器很有可能将新生成的局部变量放置在同一个内存地址,所以新的一个循环中的k与上一次循环中的k,从语义上来说已经是不同的了,但是从实现上来说,却分配了同一个地址。所以多次循环操作的是同一个地址中的值,也就会出现可以累加的情况了。
理解和讨论之前请先学会如何观察!
计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构……
对学习编程者的忠告:
多用小脑和手,少用大脑、眼睛和嘴,会更快地学会编程!
眼过千遍不如手过一遍!
书看千行不如手敲一行!
手敲千行不如单步一行!
单步源代码千行不如单步Debug版对应汇编一行!
单步Debug版对应汇编千行不如单步Release版对应汇编一行!
VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
(Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)