恭喜 “Visual C++” 版开张大吉,特此一问,请会C/C++的DFW过来看看,用delphi的兄弟也可以来瞧瞧(300分)

  • 主题发起人 主题发起人 小人物
  • 开始时间 开始时间

小人物

Unregistered / Unconfirmed
GUEST, unregistred user!
清华大学教授谭浩强 ,浙江大学教授钱能,谁对谁错???请您评说。(关于'/0'的问题)
谭浩强的《C程序设计》,清华大学出版社
1991年7月第一版 书号:ISBN 7-320-00860-4/TP.312 定价:20元
第92页:
“需要说明的是:字符数组并不要求它的最后一个字符为'/0',甚至可以不包含'/0'。像以下这样写完全是合法的:
static char c[5]={'C','h','i','n','a'};
是否需要加'/0',完全根据需要决定。但是只要用字符串常量就会自动加一个'/0'。因此,人们为了处理方法一致,以及在程序中作相应的处理,在字符数组中也常常人为的加上一个'/0'。如:
static char c[6]={'C','h','i','n','a','/0'};

《C++程序设计教程》,钱能主编 清华大学出版社
1999年4月第一版 书号:ISBN 7-302-03421-4/TP.1858
第126页:
“如果要初始化一个字符串"hello",那么它定义的数组至少有六个数组元素,
例如,下面的代码给数组初始化,但会引起不可预料的错误:
char array[5]="hello";
该代码不会引起编译错误,但由于改写了数组空间以外的内存单元,所以是危险的。”
问:清华大学教授谭浩强与浙江大学教授钱能,谁对谁错???
或者他们都对,这是c与c++语法的不同导致数组定义的区别?
请各路大侠拔刀相助,以解我多年心头之惑。
 
事实胜于雄辩。作个实验看看不就可以了!
 
《C程序设计》是我的教材哎~不会错吧,
 
都没有说错啊
 
我用turbo c2.0做过试验
main()
{ char str[5]="China";
printf("%s", str);
}
输出的结果是正确的,但按《C++程序设计教程》里讲的,
这个程序“会引起不可预料的错误”,“是危险的”,我就有了疑惑。
我该怎么办,到底是否需要定义成 char str[6]="China";
呢?
 
来踢一脚的。
 
我没试过
 
钱能说的有误,char array[5]="hello";作为一个字符数组来说是正确的,
但是如果要当作字符串来用的话就有问题了。正如谭所说,是否需要加'/0'是根据需要
而定的。
附:声明char *array="hello"的时候实际上是生成array[6]="hello/0"。
可以用vc做测试,加上断点,查看内存就行了。
大学时钱能好像只给偶上过几堂课,感觉水平也不怎么样。
 
我试过
按照正常的来说应该加'/0'
但是如果不加'/0'也不会错的,只是使用的时候一定要注意数组的长度
 
记得加/0是肯定没有错的
 
他们说的都对。
static char c[5]={'C','h','i','n','a'};
这样写没问题,因为并没超出5个字符,但使用的时候就不能这样用:
printf("%s", c);
这时候就有可能出现不可预料的错误,当然并不一定出错,这我是有过亲身体会的。
象这样定义是不行的:char array[5]="hello";
这时候会有:
array[0] = 'h';
array[1] = 'e';
array[2] = 'l';
array[3] = 'l';
array[4] = 'o';
array[5] = '/0';
由于array[5] = '/0' 改写了数组空间以外的内存单元,所以是危险的,我就挨过把别的
内存变量给改了,为了查这个错误花了我两三天的时间。
 
我在TC2.0下试过了
main() {
int i;
char s[6]="china";
for(i=0;i<5;i++)
printf("%c",s);
printf("/n");
printf("%s/n/n",s);
getch();
}
这样输出的结果是正确的,如果把 char s[6]="china";
改成 char s[5]="china";
的话
循环输出字符肯定是正确的,而输出字符串则会出问题,屏幕上的输出结果是这样的
china
chinagΓ&amp;nbsp;&amp;#8596;&amp;#9786;&amp;#9786;
也就是说,输出时发生了越界,直到碰到'/0'时才停止输出!
 
同意jiaying说的,就是这样
 
对于
char str[5]="hello"
在内存中应该是这样的
h e l l o '/0'
就是说结尾的'/0'占用了下一个地址
如果下一个地址是一个char类型
就会被赋值为'/0'
请试试这段程序
char str[5]="hello";
char c;
1.printf(str);
2.c='1';
3.printf(str);
3可能就打印出
hello1…………
直到有一个0
我没实验过
马上test,没有错的话就不跟贴了
看来不用测试了
 
这有什么可讨论的,两个人说得都对,不过是出发点不同:
谭浩强:强调一个字符串数组的组成,这种形式在 C 中表现很多,
如:struct tagTestStru{
char name[5];
};
此时要求name 的所有5个字符全部有效,因此最后一个字符肯定不必要是 '/0';
如果实在不放心,可以看看 MySQL 源码或 SDK 头文件,很清楚。
钱能:这种形式是将数组作为一个单独处理的”串“,注意,用”“括出是因此
C 不存在真正的字符串,因此为实现一个”串“,就必须分配一段内存(数组),
这个数组必须有界--------- 于是就有 '/0' 的需要,并且这是 Windows 规定的
串界表达 (null-terminate)。不过,严格地说,'/0' 并不能说就是一个串的结
束,比如:GetPrivateProfileSection(),返回的是一个包含 '/0'(以连续两个'/0'
表示串结束)。因此可以看出 ------- 这只是一种环境规范,而非语言本身规范!
 
应该需要'/0'呀,如果不加,会造成不可预料的错误。
 
补充一点:事实上 Delphi 的 AnsiString 也不是 null-terminate 串,它是用 S[0]
表达的串长来指示一个串的结束。只有与 char* 兼容的 PChar 才要求是 NULL 终止串。
 
char array[5]="hello";
这样肯定是不对的,当然它并不一定立刻就会引发错误,但是绝对是一个隐患,原因上面
的已经说得很清楚了。
 
学C的时候好像记得,现在全忘光光了
我也是谭浩强的《C程序设计》入门的~
 
hehe,混分..
 
后退
顶部