A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 完美世界 中级黑马   /  2014-6-26 19:14  /  2172 人查看  /  16 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

先看代码:
#include <stdio.h>
int main()
{
    char c[]="ok";
    int a=-65;
    char c1[]={'n','o'};
    printf("%s\n",c);
    return 0;
}
(我用的苹果本)我的运行结果是:no????

我想问的是:4个问号我可以理解,但是在其后没有输出字符串ok,就说明4个问号后还有一个字符是'\0'。那是不是说明c1字符数组后有5个字节?我想的是在c1字符数组后的存储单元应该是变量a,有4个字节。变量a之后是c字符数组。

是不是我想的那个地方有出入?请大家帮忙看看~~

评分

参与人数 1技术分 +1 收起 理由
傘が咲く + 1

查看全部评分

16 个回复

倒序浏览
代码打错了一行。。输出语句应该是:printf("%s\n",c1);
回复 使用道具 举报
本帖最后由 诸葛佰通 于 2014-6-26 22:19 编辑

不知道你要的是不是这个结果?我的也是苹果本,完全拷贝你的代码,打印出来是有ok的。
如下图:



回复 使用道具 举报
{:2_31:}{:2_31:}{:2_31:}{:2_31:}{:2_31:}{:2_31:}
回复 使用道具 举报
我的也是ok啊 我改成c1 就变成 no????^ok 这个了,怎么会是on ,楼主在试试??
回复 使用道具 举报
c1是个字符数组,不是字符串,后面????是因为你没定义字符数组的长度。若在字符数组里面加个‘\0’应该就么有????号了,楼主也可以用strlen函数试试
回复 使用道具 举报
董月峰 发表于 2014-6-27 07:25
c1是个字符数组,不是字符串,后面????是因为你没定义字符数组的长度。若在字符数组里面加个‘\0’应该 ...

那三个变量的定义顺序,以及输出方式是我故意安排的,我的疑问是:no后面不光有4个问号,最后还有一个'\0'否则就不会停下输出。然而c1字符数组没有'\0'那么会接着输出他后面内存地址中的数据也就是我定义的int型的a,而a是4个字节,一个字符是一个字节。会出现4个问号加一个'\0'让我很疑惑~~
回复 使用道具 举报
诸葛佰通 发表于 2014-6-26 22:17
不知道你要的是不是这个结果?我的也是苹果本,完全拷贝你的代码,打印出来是有ok的。
如下图:

图看不到啊~~~最后输出的时c1,我开始写错了些成了c。看不到你得代码,不知道你是输出的哪个~~
回复 使用道具 举报
骑着飞机去看海 发表于 2014-6-26 23:26
我的也是ok啊 我改成c1 就变成 no????^ok 这个了,怎么会是on ,楼主在试试??
...

我的结果是:no????
不是on呀~,你输出的这个结果和我最后要问的道理相同。就是no后面为什么有5个字符
回复 使用道具 举报
字符串常量不是%c吗?  printf("%c\n",c);  这么写应该没问题吧
回复 使用道具 举报
1014917278 来自手机 中级黑马 2014-6-27 09:47:19
11#
内存是从大到小分配的,你在中间定义了一个整型变量,所以会出现????,我试了几次一定情况下它输出到整形变量a就结束了,后面的ok并没有输出所以4个问号
回复 使用道具 举报
1014917278 发表于 2014-6-27 09:47
内存是从大到小分配的,你在中间定义了一个整型变量,所以会出现????,我试了几次一定情况下它输出到整 ...

嗯,我问的就是,ok没有输出是因为他前面有了'\0',而且还有4个问号,也就是5个字节。而我在中间定义的int a 只占据4个字节。~
回复 使用道具 举报
完美世界 发表于 2014-6-27 10:09
嗯,我问的就是,ok没有输出是因为他前面有了'\0',而且还有4个问号,也就是5个字节。而我在中间定义的in ...

你可以打印 c1 &a 和 c 看看它们的地址.
在定义变量的时候, **它们不一定是连续存储的**, 很可能在 a 和 c 之间还有没有被赋值的内存空间, 那里可能有一个字节是 0000 0000.

我试了一下, 在我的Xcode里, a 的起始地址是 0x...28, c 的起始地址是 0x...2d, 因为 a 只占四个字节, 说明 0x...2c这个字节是空的, 而它碰巧是'\0'.
回复 使用道具 举报
嗯... 我以前也挺好奇内存中是怎么回事的, 其实还可以定义一个 char* 类型的指针, 把 a 后面地址中的内存*逐个字节*的打印出来看一下,

char *p = (char *)&a;         // 从 a 的地址开始
for (int i = 0; i < 7; i++)    // 一共查看7个字节的内容
{
        // 因为p是char*, 所以每次p+1就过一个字节
        printf("%d\n", *(p+i));    // 读取每个字节的内容, 并打印出它对应的整数值
}

打印出来会发现, 前4个字节都是负数 (-65的二进制码占的四个字节), 第五个字节是0, 第六个才是111, 即'o', 第七个是107, 即'k'.

反正, 关键就是, 变量不总是连续存储的
c1和a是连续的, a和c是不连续的, 至于为什么有的连续有的不连续我就不知道了...

回复 使用道具 举报
liulinjie 发表于 2014-6-27 15:32
嗯... 我以前也挺好奇内存中是怎么回事的, 其实还可以定义一个 char* 类型的指针, 把 a 后面地址中的内存* ...

谢谢,耐心解答。有代码还有注释~~
你说的我都看了,我在发帖之前也做了很多测试,看了MJ老师的视频,看到两个字符数组定义时地址连续了,就自己做了些测试。也在想是不是定义变量时地址不一定是连续的。你说的很有道理,还是得说谢了~
回复 使用道具 举报
我只看到你说的“我用的苹果本”表示羡慕嫉妒恨
回复 使用道具 举报
路过   沙发
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马