讨论char *ps="abc"和char s[]="abc"
请各位高手和朋友们一起从内存这个本质东西讨论一下这两个共同点,和不同点! 问题点数:100、回复次数:45Top
1 楼hhdsq(流氓宝宝)回复于 2005-04-03 11:01:55 得分 5
char* ps="abc";
表示ps是指向一个常量字符串的指针,其实它的类型应该是const char*。不可以通过此指针来修改常量字符串的内容。
char s[]="abc";
s是个数组,它的内容是"abc",等于是把常量字符串"abc"的内容复制给了s。可以修改s的内容Top
2 楼arrowcy(长弓手)回复于 2005-04-03 11:18:15 得分 1
同意楼上,其实这个问题前面几乎天天都在讨论Top
3 楼szws(克米帅)回复于 2005-04-03 11:46:20 得分 5
都给说了,举个例子吧
char *ps="abc";
char s[]="abc" ;
s[0]='e';//right可以修改s的内容
*ps='e';//wrong不可以通过此指针来修改常量字符串的内容Top
4 楼copygirl(wa!)回复于 2005-04-03 11:50:48 得分 1
我一直把它们看成相同的东西。Top
5 楼cxc014(有心插柳柳不活,无心栽花花开花?)回复于 2005-04-03 11:51:03 得分 2
ps = "e"; //right
s = "e"; //wrongTop
6 楼aresteed(不夫)回复于 2005-04-03 13:00:04 得分 2
如果char *a=ps的话那a的内容可以改变吗?Top
7 楼kobefly(科比--网络学习中)回复于 2005-04-03 13:07:27 得分 5
char* ps="abc";
表示ps是指向一个常量字符串的指针,字符串是存储在常量区的,不能修改
比如
ps[1]= 'c';会造成运行时错误
char s[]="abc";
是存储在栈上的,可以修改Top
8 楼zengwujun(月之海 为linux入门奋斗100天)回复于 2005-04-03 13:07:42 得分 5
541: char *ps="abc";
00401028 mov dword ptr [ebp-4],offset string "abc" (0041f01c)
542: char s[]="abc" ;
0040102F mov eax,[string "abc" (0041f01c)]
00401034 mov dword ptr [ebp-8],eax
从存储角度来讲,ps得到得是string的偏移
s得到的是一个常量值"abc"。
在编译后,s会被常量折叠,被替换成"abc"Top
9 楼277894613(秒大刀)回复于 2005-04-03 13:11:55 得分 5
//Dev_cpp
#include <iostream>
#include <stdlib.h>
using namespace std;
int main(int argc, char *argv[])
{
char* pc="abc";
char ac[]="abc";
pc="Xbc";
ac[0]='X';
cout<<"pc\t"<<pc<<endl;
cout<<"ac[]\t"<<ac<<endl;
system("PAUSE");
return 0;
}
/*
输出为:
pc Xbc
ac[] Xbc
*/Top
10 楼zengwujun(月之海 为linux入门奋斗100天)回复于 2005-04-03 13:12:00 得分 0
所有s的值在整个程序运行期间都是不变的,而*p可以Top
11 楼answersha(水少爷)回复于 2005-04-03 13:16:39 得分 0
个人认为
char a[] = char *const a
ps 相当 const char*Top
12 楼ycom__net(一恒)回复于 2005-04-03 13:27:33 得分 5
zengwujun(月之海) (
541: char *ps="abc";
00401028 mov dword ptr [ebp-4],offset string "abc" (0041f01c)
542: char s[]="abc" ;
0040102F mov eax,[string "abc" (0041f01c)]
00401034 mov dword ptr [ebp-8],eax
从存储角度来讲,ps得到得是string的偏移
s得到的是一个常量值"abc"。
在编译后,s会被常量折叠,被替换成"abc"
正学汇编,学习!!!Top
13 楼zhousqy(标准C匪徒)(甩拉,甩拉)回复于 2005-04-03 16:00:10 得分 0
同意楼上的银们。Top
14 楼beyond429(Stellar.He)回复于 2005-04-03 16:43:19 得分 10
char* pS=”ABC”,在常量区分配了4个字节的空间,分别将字符’A’、 ’B’、 ’C’和字符串结束标志’\0’存储进去,同时在变量区定义了一个字符型的指针变量pS,然后将pS指向”ABC”的首地址。因为”ABC”在常量区,是常量,所以*pS的值是不能被改变的。例如:*pS=”abc”,它想将字符串”abc”的值附给*pS就是错误的。而pS本身是字符型的指针变量,是变量,所以它的值是可以被改变的。
char pS[ ]=”ABC”初始化了一个长度为4个字节的字符串数组。数组的值可以改变,例如:strcpy(pS,”ab”)是正确的,执行完后,字符串数组pS的值为”CD”。而对于char* pS=”ABC”,执行strcpy(pS,”ab”)则是错误的。对于char pS[ ]=”ABC”中的pS,它是字符串数组的首地址,是一个常量,因此它的值是不能被改变的,所以如果要对它进行附值是不被允许的,是错误的。
在两者中的pS虽然都表示的是地址,但在char* pS=”ABC”中的pS是变量,而在char pS[ ]=”ABC” 中的pS却是一个常量。
Top
15 楼Konker_Roc()回复于 2005-04-03 16:54:54 得分 5
从存储角度看,
char *ps="abc";
如果是在某个函数里面写,ps是局部变量,类型为字符指针,而"abc"是分配在全局数据区的常量部分,只是用ps指向它的首址,也就'a'的地址。如果在函数外写,则ps也是全局数据区里面,而"abc"同上。
char s[]="abc"
如果是在某个函数里面写,s是局部数组,其值是一个地址('a'的地址),本身不是变量,是个常量。
如果在函数外写,s是全局数组,其值是一个地址('a'的地址),本身不是变量,是个常量。
Top
16 楼LOWGUN(两只白袜)回复于 2005-04-03 16:58:12 得分 0
前面都才讨论过的这个问题嘛.大家都解释的很明白了.Top
17 楼liwei6797(对倒二五条)回复于 2005-04-03 17:09:30 得分 0
markTop
18 楼Rubi(浪迹Csdn各个板块!MS-Borland-IBM-SUN-水区-在去哪里呢?)回复于 2005-04-03 19:40:08 得分 0
en,细细品析中Top
19 楼MagicCarmack(MagiC++)回复于 2005-04-03 21:00:43 得分 2
char *ps="abc";
char* T它的类型就就是适当类型的const char T[];
很多书上都有讲!Top
20 楼visual4825()回复于 2005-04-03 22:52:59 得分 0
@_@Top
21 楼opec(狂风基督)回复于 2005-04-04 06:08:06 得分 0
我看beyond429(CSDN后人) 的回复要吐血了
怎么感觉前后不对样
Top
22 楼heroboy2000(动感超人)回复于 2005-04-04 07:38:05 得分 2
char* ps="abc";
char s[]="abc";
可以return ps;
但是return s;就是错的,因为数组的空间在栈上。Top
23 楼weiym(磨刀霍霍向猪羊)回复于 2005-04-04 08:55:56 得分 0
@_@Top
24 楼steedhorse(晨星)回复于 2005-04-04 08:58:58 得分 5
char* ps="abc";
char s[]="abc";
ps指针变量本身在栈上,指向的内容在静态存储区;
s只是个数组名,本身不占运行时程序的空间,只是在源程序中用来标记一个字符数组(即其首地址),而数组也是存储在栈上的。Top
25 楼steedhorse(晨星)回复于 2005-04-04 09:03:09 得分 5
一个更需要注意的例子是:
const char* f1()
{
char *p = "abcd";
return p;
}
const char* f2()
{
char s[] = "abcd";
return s;
}
其中f1是没问题的,而f2是危险的。因为f1返回后,局部变量p指向的静态存储区的内容还在;而f2返回后,局部数组占用的内存已经不再有效了,如果再引用,就可能出现不良的后果。Top
26 楼AtaLoss0202(星空天宇)回复于 2005-04-04 09:09:19 得分 0
建议楼主买本C++ Primer 3rd Edition看看,所有类似问题都将被清晰解决.Top
27 楼sharkabc(shark)回复于 2005-04-04 10:49:05 得分 5
指针和数组存在着一些本质的区别。当然,在某种情况下,比如数组作为函数的参数进行传递时,由于该数组自动退化为同类型的指针,所以在函数内部,作为函数参数传递进来的指针与数组确实具有一定的一致性,但这只是一种比较特殊的情况而已,在本质上,两者是有区别的。
数组s需要在内存中占用3个字节的空间,这段内存区通过名字s来标志。指针ps则需要4个字节的空间来存放地址,这4个字节用名字ps来标志。其中存放的地址几乎可以指向任何地方,也可以哪里都不指,即空指针。目前这个ps指向某地连续的3个字节,即字符串“abc”。Top
28 楼daylove(爱晶如梦)(昨夜西风调碧树,独上高楼,望尽天涯路……)回复于 2005-04-04 11:54:24 得分 1
存储地方不一样,一个在静态存储娶,另一个在栈上。Top
29 楼zoadex(笑书侠)回复于 2005-04-04 13:39:17 得分 0
up~Top
30 楼sunv1004(天道酬勤)回复于 2005-04-04 14:44:21 得分 1
昨天还为这样的问题在郁闷,谢谢了呀!
Top
31 楼sleepti(努力学习,挚爱C++)回复于 2005-04-04 17:08:33 得分 0
学习
我一直以为是一样Top
32 楼wangjianddy(~~~~>_<~~~~)回复于 2005-04-04 17:17:44 得分 0
gzTop
33 楼Pipiloo(皮皮鲁)回复于 2005-04-04 21:09:53 得分 5
541: char *ps="abc";
00401028 mov dword ptr [ebp-4],offset string "abc" (0041f01c)
542: char s[]="abc" ;
0040102F mov eax,[string "abc" (0041f01c)]
00401034 mov dword ptr [ebp-8],eax
从存储角度来讲,ps得到得是string的偏移
s得到的是一个常量值"abc"。
在编译后,s会被常量折叠,被替换成"abc"
请教zengwujun(月之海) :
前一句能明白,后一句不理解。eax中保存的是什么?是‘a'吗?
“常量折叠”后[ebp-8]处的数据结构是什么样的?Top
34 楼steedhorse(晨星)回复于 2005-04-04 21:17:47 得分 5
不是,就是abc加一个结束符,eax是32位寄存器,一次可以借助用来移动4个字符。这个例子中加上字符串结束符,总共才4个,所以一次就可以接住eax“拷贝”过去了。
如果再多些,或许你就可以看明白了:
31: char s[] = "abcdefghijklmn";
0040114F mov eax,[string "abcdefghijklmn" (0042b01c)]
00401154 mov dword ptr [ebp-14h],eax
00401157 mov ecx,dword ptr [string "abcdefghijklmn"+4 (0042b020)]
0040115D mov dword ptr [ebp-10h],ecx
00401160 mov edx,dword ptr [string "abcdefghijklmn"+8 (0042b024)]
00401166 mov dword ptr [ebp-0Ch],edx
00401169 mov ax,[string "abcdefghijklmn"+0Ch (0042b028)]
0040116F mov word ptr [ebp-8],ax
00401173 mov cl,byte ptr [string "abcdefghijklmn"+0Eh (0042b02a)]
00401179 mov byte ptr [ebp-6],cl
上面14个字符,加一个字符串结束符,一共15个,所以3次dword,一次word,一次byte,3 * 4 + 2 + 1 = 15。Top
35 楼steedhorse(晨星)回复于 2005-04-04 21:18:39 得分 0
打错字了,
一次就可以接住eax“拷贝”过去了。
一次就可以借助eax“拷贝”过去了。
Top
36 楼wupeizhe(菜鸟上路)回复于 2005-04-04 22:28:08 得分 0
看看 c标准与实现 从汇编的角度解释的,受益~!!~Top
37 楼wuyupu(wuyupu)回复于 2005-04-04 22:35:08 得分 2
我认为如果不做为行数参数的话,这两个是不一样的,*ps是指向char型的指针,而ps[]是一个字符数组(字符串),但是当它们做为函数参数时我认为时一样的,因为无论时*ps还是ps[],实际上都是传递的一个指针,如果传递ps[]的话,这个指针指向该字符串的首地址。 才疏学浅,高手勿笑Top
38 楼crcr(游侠)回复于 2005-04-04 22:41:39 得分 2
char* ps="abc";
表示ps是指向一个常量字符串的指针,其实它的类型应该是const char*。不可以通过此指针来修改常量字符串的内容。
char s[]="abc";
s是个数组,它的内容是"abc",等于是把常量字符串"abc"的内容复制给了s。可以修改s的内容
Top
39 楼crcr(游侠)回复于 2005-04-04 22:47:51 得分 5
char* pS=”ABC”,在常量区分配了4个字节的空间,分别将字符’A’、 ’B’、 ’C’和字符串结束标志’\0’存储进去,同时在变量区定义了一个字符型的指针变量pS,然后将pS指向”ABC”的首地址。因为”ABC”在常量区,是常量,所以*pS的值是不能被改变的。例如:*pS=”abc”,它想将字符串”abc”的值附给*pS就是错误的。而pS本身是字符型的指针变量,是变量,所以它的值是可以被改变的。
char pS[ ]=”ABC”初始化了一个长度为4个字节的字符串数组。数组的值可以改变,例如:strcpy(pS,”ab”)是正确的,执行完后,字符串数组pS的值为”CD”。而对于char* pS=”ABC”,执行strcpy(pS,”ab”)则是错误的。对于char pS[ ]=”ABC”中的pS,它是字符串数组的首地址,是一个常量,因此它的值是不能被改变的,所以如果要对它进行附值是不被允许的,是错误的。
在两者中的pS虽然都表示的是地址,但在char* pS=”ABC”中的pS是变量,而在char pS[ ]=”ABC” 中的pS却是一个常量。
Top
40 楼crcr(游侠)回复于 2005-04-04 22:52:12 得分 2
char a[] = char *const a
ps 相当 const char*
Top
41 楼moonranger(狂热的菜鸟)回复于 2005-04-05 11:41:00 得分 5
#include <stdio.h>
int main()
{
char *p="Jerry";
*p='k';
puts(p);
getch();
}
刚刚在TC里调试通过的程序!
难道真的就像他说的
char* ps="abc";
表示ps是指向一个常量字符串的指针,其实它的类型应该是const char*。不可以通过此指针来修改常量字符串的内容。
这样吗?Top
42 楼ghostsG(GCool)回复于 2005-04-08 15:19:08 得分 0
upTop
43 楼ZhangYv(迎着朝阳,走向地狱)回复于 2005-04-08 15:34:52 得分 0
[]就是*解地址,实际上是一样的。Top
44 楼ZhangYv(迎着朝阳,走向地狱)回复于 2005-04-08 15:37:37 得分 2
哦,我是说语义上。
*p和p[]意思是不一样的。
p[] = "xxx",是数组,[]缺省是后面字符串长度,编译器可以自己算。
*p = "xxx",是常量Top
45 楼crcr(游侠)回复于 2005-06-24 20:19:05 得分 0
char* ps="abc";
表示ps是指向一个常量字符串的指针,其实它的类型应该是const char*。不可以通过此指针来修改常量字符串的内容。
char s[]="abc";
s是个数组,它的内容是"abc",等于是把常量字符串"abc"的内容复制给了s。可以修改s的内容
Top
相关问题
- char *a="abc"和char c[4]="abc"的区别
- 问char a[3]="abc" ; 与char a[3]={"abc"} 有什么 区别么, thanks
- 他们有何区别?const char* str="abc" 与 const char str[]= "abc"
- const 说明符的两个选择题,const char * node="ABC"和 char *const node="ABC"
- char
- char
- 在线等候 char * aaa 和CString abc之间的转换问题
- char str[]="I love abc";printf("%s\n",str[1]);提示非法访问
- 问题简单:char *abc[100]={"abc","df","dsgd",NULL.....},增加一个值!--在线等,立即给分!
- 考你还给你加分,char abc[4]显示在编辑框中




