BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / cpp / #7687同步于 2008/5/28
CPP机器人发帖

常见问题

Xer
2008/5/28镜像同步0 回复
如果是第一次提问,强烈建议先阅读一下置顶的提问的智慧。 欢迎指出错误和补充。 ======================================================================================================== 00 版面指南 使用问题关键字搜索版面帖子 版内精华区: http://forum.byr.edu.cn/wForum/elite.php?path=%2Fgroups%2Fsci.faq%2FCPP 本版置顶常用资源链接:各种编译器,IDE,电子书...... ======================================================================================================== 01 资源指南 Google(谷歌)搜索引擎: http://www.google.cn/ C-FAQ主页(英文版): http://c-faq.com/ 中文翻译: http://c-faq-chn.sourceforge.net/ ======================================================================================================== 02 C推荐图书 (排名不分先后,请根据自己的需要选择) 入门: 《C How to Program》 中文译名:C程序设计教程 《The C Programming Language》 中文译名:C程序设计语言 提高: 《C Traps and Pitfalls》 中文译名:C陷阱与缺陷 《Expert C Programming》 中文译名:C专家编程 ======================================================================================================== 03 C入门讨论:http://forum.byr.edu.cn/wForum/disparticle.php?boardName=CPP&ID=1681&pos=5 学过C++再学C:http://forum.byr.edu.cn/wForum/disparticle.php?boardName=CPP&ID=6068&pos=1 ======================================================================================================== 04 C++推荐图书 (排名不分先后,请根据自己的需要选择) 入门: 《C++ How to Program》 中文译名:C++程序设计教程 C++大学教程 《C++ Primer》 提高: 《The C++ Programming Language》 中文译名:C++程序设计语言 《Effective C++》 《Thinking in C++》 中文译名:C++编程思想 高级: 《Inside the C++ Object Model》 中文译名:深度探索C++对象模型 ======================================================================================================== 05 C++入门讨论:http://forum.byr.edu.cn/wForum/disparticle.php?boardName=CPP&ID=17785 学过C再学C++:http://forum.byr.edu.cn/wForum/disparticle.php?boardName=CPP&ID=2001&pos=163 ======================================================================================================== 06 一些语言的对比 C和C++:http://forum.byr.edu.cn/wForum/disparticle.php?boardName=CPP&ID=17783 C++和Java:http://forum.byr.edu.cn/wForum/disparticle.php?boardName=CPP&ID=8837&pos=1 C++和C#:http://forum.byr.edu.cn/wForum/disparticle.php?boardName=CPP&ID=1206&pos=2 C,C++和C#:http://forum.byr.edu.cn/wForum/disparticle.php?boardName=CPP&ID=4138&pos=1 ======================================================================================================== 07 推荐编译器/集成开发环境? windows下vc不错但是很大,小一点免费的有dev c++ lcc,单独编译器icc也很好,gcc的偏好者可以用mingw+gcc或者cygwin+gcc。 linux下当然的gcc。 IDE有code::blocks,下载地址见置顶常用资源。它的好处是体积小,而且是免费和开源的,有windows和linux的版本。 ======================================================================================================== 08 程序运行闪一下就没了,看不到运行结果。 程序头添加#include <stdlib.h>,程序结束处添加system("PAUSE");或者用命令行运行。 ======================================================================================================== 09 i=(++i)*(++i)的值是多少 和编译器相关,编码推荐不使用这种风格的表达式,愿意研究的请自行研究,本版不讨论。 另:同一变量在一个表达式中两次作为左值出现时,表达式的值不确定。比如,(i++)+(i++),i=i++ ======================================================================================================== 10 VS(VC)由于各种原因出错怎么办? 1 google或百度出错信息; 2 可能是安装程序有问题,重新找一个安装程序; 3 卸载,找优化大师清理垃圾文件和注册表,重启再安装一次; 4 可能是VS(VC)版本和Windows不兼容,可以考虑换VS(VC)2005或2008或更高版本; 5 重装系统; 6 打电话给M$售后服务。 ======================================================================================================== 11 TC编译提示找不到.obj文件 .h文件。 TC已经落伍了,跟不上标准,不建议使用。 ======================================================================================================== 12 char *p="abc" 与 char p[]="abc" 的区别 1.以字符串形式出现的,编译器都会为该字符串自动添加一个0作为结束符,如在代码中写"abc",那么编译器帮你存储的是"abc\0" 2."abc"是常量吗?答案是有时是,有时不是。 不是常量的情况: "abc"作为字符数组初始值的时候就不是,如 char str[] = "abc"; 因为定义的是一个字符数组,所以就相当于定义了一些空间来存放"abc",而又因为字符数组就是把字符一个一个地存放的,所以编译器把这个语句解析为 char str[3] = {'a','b','c'}; 又根据上面的总结1,所以char str[] = "abc";的最终结果是 char str[4] = {'a','b','c','\0'}; 做一下扩展,如果char str[] = "abc";是在函数内部写的话,那么这里的"abc\0"因为不是常量,所以应该被放在栈上。 是常量的情况: 把"abc"赋给一个字符指针变量时,如 char* ptr = "abc"; 因为定义的是一个普通指针,并没有定义空间来存放"abc",所以编译器得帮我们找地方来放"abc",显然,把这里的"abc"当成常量并把它放到程序的常量区是编译器最合适的选择。所以尽管ptr的类型不是const char*,并且ptr[0] = 'x';也能编译通过,但是执行ptr[0] = 'x';就会发生运行时异常,因为这个语句试图去修改程序常量区中的东西。 记得哪本书中曾经说过char* ptr = "abc";这种写法原来在c++标准中是不允许的,但是因为这种写法在c中实在是太多了,为了兼容c,不允许也得允许。虽然允许,但是建议的写法应该是const char* ptr = "abc";这样如果后面写ptr[0] = 'x'的话编译器就不会让它编译通过,也就避免了上面说的运行时异常。 又扩展一下,如果char* ptr = "abc";写在函数体内,那么虽然这里的"abc\0"被放在常量区中,但是ptr本身只是一个普通的指针变量,所以ptr是被放在栈上的,只不过是它所指向的东西被放在常量区罢了。 3.字符串常量的类型可以理解为相应字符常量数组的类型,如"abcdef"的类型就可以看成是const char[7] 4. "abcd"是一个指针,一个字符串指针,指向的字符串一般保存在常量数据区,不可修改。 所以如果有char *p="abcd";然后*p=9;则会发生运行时错误。 "abcd"[2]值为'c',"abcd"[2]=5显然是不对的,写成p[2]=5或者*(p+2)=5也是不对的。 如果真的需要使用"abcd"作为指针,建议写为const char * p="abcd"; 如果是初始化字符串数组,建议写为char p[]="abcd"; 如果p为指针,需要初始化,应该是char *p;p=malloc(STR_SIZE);strcpy(p,"abcd"); ======================================================================================================== 13 数组名是地址么?它和地址的差异在哪里呢? 如果运算需要的话,所有的数组都存在到它元素的指针类型的右值的隐式类型转换。说数组是本身就是地址是不科学的,而应该说数组能够自动的转化为指向他的元素的指针,这种转化是单向的,是一种退化,损失了原来数组的大小这个重要的信息。除了 sizeof 之外,其他运算符作用到数组上的时候,都要发生这种转化,即使取下标也不例外。 比如整型二维数组w[3][4], 先不要把 w 看作地址。把 w 看作三个四个元素的数组的组成的数组。 sizeof(w) 不转化 sizeof(w+0) 转化,这个和上面的结果的差异仔细观察 ww = w 转化 w[0][0] = 0 两次转化 w = NULL 无法转化 由于那么 w 是三个四个元素的数组组成的数组,那么它就可以隐式地转为指向四个元素的数组的指针。 ww = w 的时候。做了一次隐式的类型转换,从 T [3][4] 变成 T (*)[4]。 ======================================================================================================== 14 数组和指针的区别 0 假设a是数组,p是指针。比如 char a[5]; char *p; 数组和指针是完全不同的类型,当然有区别!!! 1 数组有点像label,本身不占空间,占空间的是数组元素。 指针本身占空间,大小为sizeof(T*),当然指向的内容也占空间。 2 a 和 &a 类型不同,但是“地址”相同,都是label标记的地址。 3 sizeof(a) 等于数组元素的大小 乘以 元素的个数 sizeof(p) 指针本身的大小,其值在32位机器上一般等于4。 4 数组本身不能改变,比如a=b或a++都是错误;指针可以改变。数组可以赋值给指针; 5 函数形参数组完全等同于指针。形象说编译器把数组形参编译为指针形参,也可以说函数声明中不存在数组(形参或返回值)。 6 数组的数组和指针的指针完全不同,无法转换。 ======================================================================================================== 15 出现“访问违例”,“该内存不能为read”,“段异常”等情况是什么原因? 一般是程序中数组访问越界,指针没有正确赋值而指向了错误的地址所造成的。应该仔细检查程序中的指针的值。 ======================================================================================================== 16 do{...}while(0)用途 这是一个奇怪的循环,它根本就只会运行一次,为什么不去掉外面的do{..}while结构呢?我曾一度在心里把它叫做“怪圈“。原来这也是非常巧妙的技巧。在工程中可能经常会引起麻烦,而上面的定义能够保证这些麻烦不会出现。下面是解释: 假设有这样一个宏定义 #define macro(condition) \ if(condition) dosomething() 现在在程序中这样使用这个宏: if(temp) macro(i); else doanotherthing(); 一切看起来很正常,但是仔细想想。这个宏会展开成: if(temp) if(condition) dosomething(); else doanotherthing(); 这时的else不是与第一个if语句匹配,而是错误的与第二个if语句进行了匹配,编译通过了,但是运行的结果一定是错误的 。 为了避免这个错误,我们使用do{….}while(0) 把它包裹起来,成为一个独立的语法单元,从而不会与上下文发生混淆。同时因为绝大多数的编译器都能够识别do{…}while(0)这种无用的循环并进行优化,所以使用这种方法也不会导致程序的性能降低。 ======================================================================================================== 17 为什么VC6里会出现和 VS2005/2008/g++/C++ 书中不一样的情况? 因为VC6不符合C++标准,请使用符合C++标准的编译器 ========================================================================================================
订阅后,新回复会通过你的通知中心匿名送达。
0 条回复
暂无回复 · 你可以订阅本帖等待新回复。