关于C/C++ 一些自己遇到的问题以及解惑
|
文章目录
???????有些自己遇到的,有一些是通过群友的提问应发的,问题本身的价值可能并不高,但其背后的原因才是我们应该学习的,下面我们来看看。 1.数组越界造成的死循环???????有一位朋友在群里发了该代码,并说该代码导致了死循环???
???????废话少说,上工具,我们来分析分析。
???????Dev下的程序并无异常???????我们来看看vs2015的表现,虽然是正常输出内容,并没有造成死循环,但是弹出了一个异常~ 。这个异常是由于我们数组越界造成的,而数组越界又是一种未决行为,编译器不会做任何处理,但是vs2015还是义务的帮我提示了异常,所以Dev和vs该用哪一个编译器,心里有数了吧?
???????那么为什么会产生这样的效果呢,揭秘如下. 若是内存递减分配,对于数组和i的内存分配如下:
若是内存递增分配,对于数组和i的内存分配如下:
???????现在可能就有人问了,为什么递减分配 i和iarray[2]挨着,而递增i就和iarray[0]挨着,其实这个不难理解,*(iarray+1)一定比*(iarray)的地址高不是吗,对于递减分配,必须倒着来分配,对于递减这种分配模式,iarray[3]的地址就是i的地址,iarray[3]=0便是i=0,这样一来便导致了i的值又重新被赋值为0,导致了死循环,然后,注意,没有完,之所以i会跟在数组后面,是因为字节对齐,对于32位来说是4字节,对于64位来说是8字节,当数组内容不足以字节对齐,i就会分配在其旁边,或者说是后面,当数组正好有8个元素,i就不会跟在数组后面,也就不会造成死循环,所以造成死循环一是编译器分配内存方式,二是字节对齐的问题. ???????经测试,博主所使用的dev和vs2015,以及一些编译器会在数组和i的地址之间,用一小块内存,用来避免两者,从而一定程度上解决死循环问题,但当越界过大,还是会造成死循环.所以在使用对内存的操作上,应格外小心…
2.int main(int argc,char* argv[])里面的参数有什么作用????????首先可以告诉大家的是对于单纯的C语言,main里面的参数对于我们学习C来说,并不重要,标准形式有两种int main(int argc,char* argv[])和int main(void),在实际的学习使用中,我们使用int main(void)这种形式就可以了,当然,你要是感觉酷一点可以用int main(int argc,char* argv[]),如果你还想知道int argc,char* argv[]这种参数的作用,那么请往下看。
其实相当于是调用了exe,exe里面的函数利用参数工作,而exe也同样可以利用参数工作,那么如何输入参数呢,告诉大家几张方法: 1.直接在命令行输入 start 路径 参数1 参数2 参数3 2.我们将编译好的程序,快捷方式放到桌面,右键选择属性,在其目标的文本框 exe文件后面 加入参数
3.最后一个也就是直接在我们的IDE进行设置,例如我所使用的vs2015,右键项目->属性,在调试页面可以看到一个命令参数。
好了,main的参数就说到这里,悄悄告诉大家,其实main还有第三个参数:char *envp[],如果大家有兴趣,可自行研究研究。 3.程序代码区、文字常量区、静态区(全局区)、堆区、栈区???????为什么说这个,原因在图中:
???????群里在讨论链表,一位名叫C语言信赖代考的网友讲了一句清除链表只需要释放头节点就行了,不用一个一个删,我看到了,于是好意提醒了一句,结果这位网友告诉我头节点后面连着所有节点,只需要释放头节点就行了,一看此现状,我就没再与他讲理了。刚奇葩的是这个哥们私聊我说有单子给他,这我敢给啊,再顺便讲一句,不要随随便便叫人代考啊。。。。我们进入正题。 ???????这位网友之所以会怎么说,应该是没有理解malloc/new,也就是malloc的内存申请在哪,就是栈区和堆区问题,但是因为程序代码区、文字常量区、静态区(全局区)、堆区、栈区这些东西常出现在一起,索性也就放在一起说了。 ???????我查找了大量的有关博文,大多数有关博文都有怎么一张图,如果说以前,我可能会同意,但是现在我对图中栈区的向下增长有一些疑惑,就拿我们刚开始数组死循环的内存分配来说,内存两种分配模式,递增,递减,所以我觉得这个图还有待考证。
同时我们可以右键项目,链接器,系统,可以看到堆保留大小和堆栈保留大小。
然后再说一下malloc对应free,new对应delete,new,delete涉及构造函数和析构函数,不可混用,若是C++,应使用new。 4.函数指针 指针函数 指针数组 数组指针 傻傻分不清
上面出现的括号都是必要的,不可省略,说其是一种格式也不为过,指针XX和XX指针分不清主次,可以像我一样在两者之间加上(样式的),应该会方便理解。 5.return continue break return 0 exit
其实这两个没什么说的,return 和 exit可能在书中不常见。
6.最大值加1等于最小值?(一图看懂)我们可以把变量的取值范围当作是汽车的里程表,一来为了好理解,二来确实是这样的,拿char来说:
7.精度问题
这位网友的问题很有意思,这个案例也是很好的图示了下面我要说的话,这是众多初学者的一个理解错误,每一本语言书都会告诉你单精度类型有效范围是7位,双精度类型有效范围15位,这就给大家造成一种错觉,认为只能存15位,其实是错了,它所指的15位指的是精度问题,就是图中的样子,它可以存储30位甚至更多,但是它的精度只有前15位,就是超过了15位,一起数字都化作了0。之所以可以保存到30多位,和浮点数的存储有关,浮点数是用科学记数法存储的,有关浮点数的定义,这个就涉及到计算机组成原理了,还是比较难的,大家有兴趣可以搜索IEEE754浮点数的标准,里面有关于浮点数的存储过程。 最后来一只可爱的猫猫,创作不易,求关注,求收藏!
(编辑:北几岛) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |

















