字符数组与字符串输出的问题

mengxiang2003 2007-03-09 04:42:23
#include <stdio.h>

int main(int argc, char *argv[])
{
char c[4]={'a','b','c','d'};
char d[]={'a','b','c','d'};
char e[] = "abcd";
int sc = sizeof(c);
int sd = sizeof(d);
int se = sizeof(e);

printf("sc:%d sd:%d se:%d\nc:%s\nd:%s\ne:%s\n",sc,sd,se,c,d,e);
getchar();
return 0;
}
上面这段程序在win-tc中的输出结果是
sc:4 sd:4 se:5
c:abcdabcdabcd
d:abcdabcd
e:abcd
为什么c和d会连续输出abcd那
...全文
1374 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
systemthink 2007-03-12
  • 打赏
  • 举报
回复
字符指针和字符数组 char* s1="hello"; char s2[]="world"; 两个表达式的含义是一样的. 如果讲不同之处的话,VC6中编译时,对这两种定义进行了不同的处理; char *s1 = "hello"; 中的"hello",编译时指针指向的区域位于PE文件的.rdata节中,是只读的.


字符指针和字符数组

char* s1="hello";

char s2[]="world";
两个表达式的含义是一样的.
如果讲不同之处的话,VC6中编译时,对这两种定义进行了不同的处理;
char *s1 = "hello"; 中的"hello",编译时指针指向的区域位于PE文件的.rdata节中,是只读的.
不信的话,你可以试试:

main()
{
char *s1="hello";
char s2[]="world";

*(s2+2)='x'; //正确
*(s1+2)='x'; //执行时出错.
}

1.严格的说两个表达的意思是不完全一样的,因为前者是个字符串指针,这个指针S1所存的地址就是存储字符串前8个字节即hello/n/n/n的那个地址。
2.而后者是字符数组。每个字符都有一个独立的地址。

BEN1978 2007-03-11
  • 打赏
  • 举报
回复
lz注意,改成如下运行,就不是你看的结果了
至于为什么,楼上几位都说了

int main(int argc, char *argv[])
{
char e[] = "abcd"; //调了一下顺序
char c[4]={'a','b','c','d'};
char d[]={'a','b','c','d'};

int sc = sizeof(c);
int sd = sizeof(d);
int se = sizeof(e);

printf("sc:%d sd:%d se:%d\nc:%s\nd:%s\ne:%s\n",sc,sd,se,c,d,e);
getchar();
return 0;
}
lengxueqingfeng 2007-03-10
  • 打赏
  • 举报
回复
呵呵,楼主的运气真好。最后刚好有一个'\0',如是没有的话,就输出到明天早上了,哈哈!
ayw215 2007-03-09
  • 打赏
  • 举报
回复
嗯,确实~~~
jixingzhong 2007-03-09
  • 打赏
  • 举报
回复
这样类型不一致的话,
存在潜在的危险。

你的情况下,
恰好在 合法内存中存在一个 \0,
否则就可能访问非法的内存空间了。

可以尝试把 e 的定义放到前面去 ~
(也就是这个 合法\0在前面,
那么 c d就可能需要访问非法空间, 程序就出错了)
jixingzhong 2007-03-09
  • 打赏
  • 举报
回复
这样的结果和你的定义方式相关 ~

在你的定义中,
c d 不是字符串,
只是字符数组,
但是输出的时候是字符串方式输出的,
不一致。

字符串方式输出,
输出操作直到遇到了 \0 后结束。

在你的定义顺序下,
(仅考虑内存偏移:)
0x00001: a <--这里开始是 c 数组
0x00002: b
0x00003: c
0x00004: d
0x00005: a <--这里开始是 d数组
0x00006: b
0x00007: c
0x00008: d
0x00009: a <--e字符串
0x00010: b
0x00011: c
0x00012: d
0x00013: \0
如上,
输出c 的时候, 直到遇到 \0,
结果就是 输出了 abcdabcdabcd

d 类似 ~
laiwusheng 2007-03-09
  • 打赏
  • 举报
回复
c:cde
d:de
e:e
millky 2007-03-09
  • 打赏
  • 举报
回复
楼上说的对,因为%s的输出方式是检测直到遇到'\0'为止,因为在输出c、d、的时候直到e的最后才检测到一个'\0',所以就一直输出到最后e了。
其实按照你的目的,你如果要%s输出的话,最好是在后面认为加上'\0',解决方法:
char c[5]={'a','b','c','d','\0'};
char d[]={'a','b','c','d','\0'};
char e[] = "abcd";
或者:char c[]="abcd";char d[]="abcd";char e[]="abcd";是等价的。
另外,不同的编译器运行的结果也是不一样的,我在dev C++,vs2005下运行的结果就大不一样。因为他们的%s输出检测方法不一样的。
北极猩猩 2007-03-09
  • 打赏
  • 举报
回复
又是老问题了。
字符串是要以'\0'结尾的。所以在输出的时候,printf从c开始一直往后找,直到找到'\0'为止结束输出。
jjjkl81 2007-03-09
  • 打赏
  • 举报
回复
假设内存地址从0x00001开始,那么c,d,e,存放如下:
0x00001: a
0x00002: b
0x00003: c
0x00004: d
0x00005: a
0x00006: b
0x00007: c
0x00008: d
0x00009: a
0x00010: b
0x00011: c
0x00012: d
0x00013: \0
由于你以字符串方式输出c d e
而字符串是以'\0'为结束符的 所以输出那种结果
iamcaicainiao 2007-03-09
  • 打赏
  • 举报
回复
abcd abcd abcd0
c d e
iamcaicainiao 2007-03-09
  • 打赏
  • 举报
回复
明显就是因为%s输出到0才为止。

abcd abcd abcd0
c d d

以上在内存中连续存放。

所以,输出c是3个abcd。
输出d是2个abcd。

taodm 2007-03-09
  • 打赏
  • 举报
回复
字符串应该以什么结尾?
healer_kx 2007-03-09
  • 打赏
  • 举报
回复
如果C是一个字符串的话,那么C的容量应该是5,而不是4。

C语言的字符串比较明确的指出了是Zero结尾的。只不过是字符串的长度为4。

char c[5]={'a','b','c','d', 0};

64,687

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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