is "hello, world" a constANT

JoshuaLi 2003-03-03 09:38:00
int main()
{
char str[] = "hello, world";
str[4] = ','; //1. ok

char *str2 = "hello, world";
str2[4] = ','; //2. runtime error
}

/*
1. 字串字面值赋值给数组可写,赋值给指针不可写(Bjarne说是为了兼容旧代码)。
仅是一个规定吗?--请解释这种差异。

2. 为何允许const字串字面值赋值给char *str2(not const char *str2)。
*/
...全文
29 32 打赏 收藏 转发到动态 举报
写回复
用AI写文章
32 条回复
切换为时间正序
请发表友善的回复…
发表回复
JoshuaLi 2003-03-04
  • 打赏
  • 举报
回复
char *str2 = "hello, world";以前根本没去想过str2[4] = ',';或这样可不可,又为何?我很自卑尚是浮汤油,很想知道更多的理论/技术细节,因此很喜欢stephen "c++ primer plus"。不像"Tc++PL"立得太高,很多细节没有涉及。几番试看此书都半途而废。多谢shornmao
shornmao 2003-03-04
  • 打赏
  • 举报
回复
to JoshuaLi(听说有人懂C++就会佩服得要死) :
>譬如vc在link不同translation unit时可能会做这些工作 --我非常渴望这部分知识。

这部分知识几乎没有什么实际价值,你只要记住不要依赖于编译器实现定义的行为就行了。
毕竟,你关心常量的地址能有什么实际帮助呢?难道你想通过指针修改常量的内容吗?这始终是未定义的行为。
JoshuaLi 2003-03-04
  • 打赏
  • 举报
回复
bcb我没试过,譬如vc在link不同translation unit时可能会做这些工作 --我非常渴望这部分知识。多谢
sandrowjw 2003-03-04
  • 打赏
  • 举报
回复
我也有点晕了,在BCB 4.0里无论如何都是不一样的,我上次试验的时候是用的gcc。
不过想回来,在linux里是分别编译的,没有project的概念,而VC里面对于project做了优化,所以结果不一样。
JoshuaLi 2003-03-04
  • 打赏
  • 举报
回复
...
extern char *k; //defined in anohter file already
char *k2 = "3k";

cout << endl << (int *)k;
cout << endl << (int *)k2;
cout << endl << (int *)"3k" << endl;
...
/*///////////////////////////////
output
0046E01C
0046E01C
0046E01C
Press any key to continue
不过我的全是一样的(vc6)*/////////
JoshuaLi 2003-03-04
  • 打赏
  • 举报
回复
啊多谢,学到新知识啦
JoshuaLi 2003-03-04
  • 打赏
  • 举报
回复
//1 ...
extern char *k; //char *k = "hello";defined in anohter file already
char *k2 = "3k";

cout << endl << (int *)k;
cout << endl << (int *)k2;
cout << endl << (int *)"3k" << endl;
...
/*///////////////output////////////////

00470284
0046E020
0046E020

the both are not as the same(vc6)*/////////


//2............................................................
extern char *k; //defined in anohter file already
char *k2 = "3k";

cout << endl << (int *)k;
cout << endl << (int *)k2;
cout << endl << (int *)"3k" << endl;
...
/*///////////////////////////////
output
0046E01C
0046E01C
0046E01C
Press any key to continue
是一样的(vc6)*/////////
JoshuaLi 2003-03-03
  • 打赏
  • 举报
回复
#include <iostream>
using namespace std;

int main()
{
char str[] = "hello, world";
str[4] = ','; //1. ok

char *str2 = "hello, world";
//str2[4] = ','; //2. runtime error

cout << (int *)"hello, world" << endl;
cout << (int *)str << endl;
cout << (int *)str[0] << endl;

cout << (int *)"hello, world" << endl;
cout << (int *)"hello, world" << endl;
cout << (int *)"hello, world" << endl;
cout << (int *)"hello, world" << endl;
}

/*
...output...
0046E01C
0012FF70
00000068
Press any key to continue
我也是指字串赋给数组时是否有两份,是回应zhouzhaohan(joejoe)的“后面只是修改这个数组的内容”,观点与你一致:) ,谢谢sandrowjw(Sandro)。

但三个都不同,
(int *)"hello, world" //0046E01C
(int *)str; //0012FF70
(int *)str[0]; //00000068
且后两个:(int *)str; (int *)str[0];为何亦不同?
*/0
aitforever 2003-03-03
  • 打赏
  • 举报
回复
学习中...
sandrowjw 2003-03-03
  • 打赏
  • 举报
回复
不好意思,说错了,上面是数组初始化,要另外开一个备份的。如果有两个指针赋值一个字符串常量那是一样的。
sandrowjw 2003-03-03
  • 打赏
  • 举报
回复
对于一般的编译器,只有一份拷贝,你可以试试printf("%d",str == str2)看,返回是1。
编译器先收集程序中所有的字符串,作为字符串常量放在额外的空间,一般相同的字符串只留一个备份的。
由于只有一个备份,所以一点改动就会造成所有和该字符串相关的变量的内容变化,所以说不要使用指针变量来改变字符串常量的内容。
heroboy2000 2003-03-03
  • 打赏
  • 举报
回复
1.第一个是数组的初始化"hello,world"就在数组理,第二个的"hello,world"是常量,str2得到的是它的地址
JoshuaLi 2003-03-03
  • 打赏
  • 举报
回复
“后面只是修改这个数组的内容”

//那么是有两份该字串的copy吗
heroboy2000 2003-03-03
  • 打赏
  • 举报
回复
2。付给str2的是const字符串的地址
JoshuaLi 2003-03-03
  • 打赏
  • 举报
回复
如何解释字串字面值的const属性
zhouzhaohan 2003-03-03
  • 打赏
  • 举报
回复
1.是给一个字符数组进行初始化,所以相当于把后面的字符串拷贝到数组中,数组的大小就是字符串的长度加一。后面只是修改这个数组的内容,所以当然没有问题。
2。是给一个字符指针初始化,将它初始化成乘放字符串"hello, world"的位置的首地址,这片地址很可能是在代码段,也许在只读的数据段,总之那段内存是应该受到操作系统保护的。所以后面写那片内存会出错。
danmao 2003-03-03
  • 打赏
  • 举报
回复
str2[4] = ',';
改为:
(*str2)[4] = ',';
sandrowjw 2003-03-03
  • 打赏
  • 举报
回复
嗯,这样就对了,我和同学做过试验,如果用一个extern引入一个字符串指针,在另外一个文件里赋值到一个常量,和当前文件里的一样的字符串常量比较,输出结果就不一样了。因为文件是编译时候的unit,不同unit里的相同的字符串常量是有各自的备份的。
JoshuaLi 2003-03-03
  • 打赏
  • 举报
回复
int main()
{
char str[] = "hello, world";
str[4] = ','; //1. ok

char *str2 = "hello, world";
//str2[4] = ','; //2. runtime error

cout << (int *)"hello, world" << endl;
cout << (int *)str << endl;
cout << (int *)(&str[0]) << endl;
cout << (int *)str2 << endl;
}

0046E01C
0012FF70
0012FF70 //谢谢,现在一样了
0046E01C
Press any key to continue
chinajiji 2003-03-03
  • 打赏
  • 举报
回复
(int *)str是首地址,但(int *)str[0];输出的是第一个字符的ASCII值,
(int *)"hello, world"输出的是在符号表中的字符串常量的首地地址.
加载更多回复(12)

69,371

社区成员

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

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