一个奇怪的c语言问题,大家帮忙看看。

哲学王 2013-03-18 10:42:17
# include <stdio.h>
main ()
{
int i,a[10]={23,34,34,654,234,4556,43,232,234,32};
for(i=0; i<=100; i++)
{
printf ("%d\n",*(a+10));
}


}

输出结果:总司从0开始一直到i<=的数。上面的就是0都100.
这是为什么?
...全文
639 37 打赏 收藏 转发到动态 举报
写回复
用AI写文章
37 条回复
切换为时间正序
请发表友善的回复…
发表回复
armsword 2013-03-20
  • 打赏
  • 举报
回复
首先越界,另一方面,那个循环没啥用啊,你打印的结果总是那一个固定地址的值。
  • 打赏
  • 举报
回复
越界了, 注意指针类型。
赵4老师 2013-03-20
  • 打赏
  • 举报
回复
引用 22 楼 shirui8653719 的回复:
引用 17 楼 zhao4zhong1 的回复:“多一少一”问题占程序员常犯错误的10%以上! VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。 对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行…… 想学习在vs 2010上调试,能不能介绍哪本书可以详细学习调试啊。谢谢啦
以下内容摘自MSDN2008,MSDN2010中应该也有对应内容: MSDN2008:开发工具和语言→Visual Studio文档→Visual Studio 中的应用程序开发→生成、调试和测试→使用Visual Studio 进行调试 ms-help://MS.VSCC.v90/MS.MSDNQTR.v90.chs/dv_vsdebug/html/590f152d-31e2-4e13-b808-a1b13e421483.htm Visual Studio 调试器 使用 Visual Studio 进行调试 发送反馈意见 您已经创建了应用程序并解决了生成错误。现在,您必须纠正那些使应用程序或存储过程无法正确运行的逻辑错误。可以用开发环境集成调试功能做到这一点。这些功能使您可以在某些过程位置停止执行,检查内存和寄存器值,更改变量,观察消息通信量,以及仔细查看代码的行为。 本节内容 Visual Studio 调试器中的新增功能 讨论 Visual Studio 2005 调试器的增强功能。 调试器安全 讨论与调试相关的安全问题。 调试设置和准备 介绍“项目属性”设置和为项目创建调试版本所必须执行的设置。还介绍远程调试设置、调试 Code Center Premium 源代码、调试部分信任的应用程序以及调试高性能群集应用程序。 调试器指南 讨论使用 Visual Studio 调试器的基本知识。涉及的主题包括:调试基础,执行控件,附加到运行的程序,实时调试,自动启动调试器,转储,断点,检查程序,处理异常,“编辑并继续”,以及在调试器中使用表达式。 调试托管代码 介绍用 Visual Basic、Visual C#、Visual J# 和 C++ 编写的托管代码的常见调试问题和技术。 调试本机代码 讨论 C 和 C++ 应用程序的一些常见调试问题和技术。 调试 Web 应用程序和脚本 描述在调试 Web 应用程序时可能会遇到的常见调试问题和技术。章节包括调试 ASP.NET 和 ASP Web 应用程序、调试 ATL Server Web 应用程序、Web 服务器调试错误和故障排除。 调试 SQL 提供有关调试 SQL Server 存储过程、函数和触发器的信息。主题包括:设置、SQL 调试示例、SQL 和混合语言调试、限制、调试扩展的存储过程、SQL 调试组件、配置 DCOM 和疑难解答。 调试用户界面参考 在调试应用程序时所使用的窗口和对话框上提供参考信息。当焦点在调试用户界面元素(如“断点”窗口)上时,按 F1 键也可以看到这些主题。 相关章节 演练:调试外接程序项目
常如意 2013-03-20
  • 打赏
  • 举报
回复
# include <stdio.h> void main () { int i,a[10]={23,34,34,654,234,4556,43,232,234,32}; for(i=0; i<=100; i++) { printf ("%d\n",*(a+10));//最多到*(a + 9) } }
赵4老师 2013-03-20
  • 打赏
  • 举报
回复
崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处。 判断是否越界访问,可以在数组的最后一个元素之后对应的地址处设置数据读写断点。如果该地址对应其它变量干扰判断,可将数组多声明一个元素,并设置数据读写断点在该多出元素对应的地址上。
赵4老师 2013-03-19
  • 打赏
  • 举报
回复
“多一少一”问题占程序员常犯错误的10%以上! 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对应的汇编并单步执行观察相应内存和寄存器变化。) 想要从本质上理解C指针,必须学习汇编以及C和汇编的对应关系。 从汇编的角度理解和学习C语言的指针,原本看似复杂的东西就会变得非常简单! 指针即地址。“地址又是啥?”“只能从汇编语言和计算机组成原理的角度去解释了。” 但我又不得不承认: 有那么些人喜欢或者适合用“先具体再抽象”的方法学习和理解复杂事物; 而另一些人喜欢或者适合用“先抽象再具体”的方法学习和理解复杂事物。 而我本人属前者。 这辈子不看内存地址和内存值;只画链表、指针示意图,画堆栈示意图,画各种示意图,甚至自己没画过而只看过书上的图……能从本质上理解指针、理解函数参数传递吗?本人深表怀疑! 这辈子不种麦不收麦不将麦粒拿去磨面;只吃馒头、吃面条、吃面包、……甚至从没看过别人怎么蒸馒头,压面条,烤面包,……能从本质上理解面粉、理解面食吗?本人深表怀疑!! 提醒: “学习用汇编语言写程序” 和 “VC调试(TC或BC用TD调试)时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。 (Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。) 想要从本质上理解C指针,必须学习C和汇编的对应关系。” 不是一回事! 不要迷信书、考题、老师、回帖; 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实! 有人说一套做一套,你相信他说的还是相信他做的? 其实严格来说这个世界上古往今来所有人都是说一套做一套,不是吗? 不要写连自己也预测不了结果的代码! 电脑内存只是一个一维二进制字节数组及其对应的二进制地址; 人脑才将电脑内存中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……
fang 2013-03-19
  • 打赏
  • 举报
回复
引用 8 楼 hxw206 的回复:
(a+10)其实就是i的地址,局部变量从堆上分配,i的地址就是ebp-0x4,a的地址就是ebp-0x4-sizeof(a).所以打印出来的其实就是i的值
是I的地址值,我刚打印出来试了下。
hello573973202 2013-03-19
  • 打赏
  • 举报
回复
数组越界,a[10]未定义;
DaiwjDev 2013-03-19
  • 打赏
  • 举报
回复
引用 13 楼 buptlijun 的回复:
引用 12 楼 cheng7068 的回复:a+10是数组越界,应该是随机数吧,正好你看到了这种结果 不是随机数,在那段代码中,就是指向的i
right
__phoenix 2013-03-19
  • 打赏
  • 举报
回复
神回复,膜拜
引用 17 楼 zhao4zhong1 的回复:
“多一少一”问题占程序员常犯错误的10%以上! VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。 对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5……
李好俊_wh1 2013-03-19
  • 打赏
  • 举报
回复
引用 12 楼 cheng7068 的回复:
a+10是数组越界,应该是随机数吧,正好你看到了这种结果
不是随机数,在那段代码中,就是指向的i
风行踩火轮 2013-03-19
  • 打赏
  • 举报
回复
a+10是数组越界,应该是随机数吧,正好你看到了这种结果
DaiwjDev 2013-03-19
  • 打赏
  • 举报
回复
引用 8 楼 hxw206 的回复:
(a+10)其实就是i的地址,局部变量从堆上分配,i的地址就是ebp-0x4,a的地址就是ebp-0x4-sizeof(a).所以打印出来的其实就是i的值
学习了,还没学过汇编
李好俊_wh1 2013-03-19
  • 打赏
  • 举报
回复
8L说的很对,自上而下分配,数组a恰好分配的是10*sizeof(int)大小,其下一个指针指向的是i的值
 int i=2,j=1,a[10]={23,34,34,654,234,4556,43,232,234,32};
这样一段代码,a+10指向的是j,a+11指向i
Lomper 2013-03-19
  • 打赏
  • 举报
回复
引用 10 楼 buptlijun 的回复:
8L说的很对,自上而下分配,数组a恰好分配的是10*sizeof(int)大小,其下一个指针指向的是i的值 C/C++ code?1 int i=2,j=1,a[10]={23,34,34,654,234,4556,43,232,234,32}; 这样一段代码,a+10指向的是j,a+11指向i
学习了……
hxw206 2013-03-19
  • 打赏
  • 举报
回复
自己调试看一下汇编代码,就一目了然了
hxw206 2013-03-19
  • 打赏
  • 举报
回复
(a+10)其实就是i的地址,局部变量从堆上分配,i的地址就是ebp-0x4,a的地址就是ebp-0x4-sizeof(a).所以打印出来的其实就是i的值
wizard_tiger 2013-03-19
  • 打赏
  • 举报
回复
LS都说了,a[10]指向了i的值。
水稻01 2013-03-19
  • 打赏
  • 举报
回复
# include <stdio.h> main () { int i,a[10]={23,34,34,654,234,4556,43,232,234,32}; for(i=0; i<=100; i++) { printf ("%d\n",*(a+10)); } } 首先呢,*(a+10)与a[10]是相同的,根据你的定义数组一共有10个元素,而数组下标是从a[0]开始的,那么最大就a[9]所以到了a[10]就越界了。所以输出i,而i是不断增长的i++,因此就输出了0-100。最后再普及下,数组是按地址存储的,这和指针是一样的。
line_us 2013-03-19
  • 打赏
  • 举报
回复
原来是这么回事。
加载更多回复(17)

69,382

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧