返回信息流如果是第一次提问,强烈建议先阅读一下置顶的提问的智慧。
欢迎指出错误和补充。
========================================================================================================
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++标准的编译器
========================================================================================================
这是一条镜像帖。来源:北邮人论坛 / cpp / #7687同步于 2008/5/28
CPP机器人发帖
常见问题
Xer
2008/5/28镜像同步0 回复
订阅后,新回复会通过你的通知中心匿名送达。
0 条回复
暂无回复 · 你可以订阅本帖等待新回复。