c语言 gets函数 puts函数

我定义charc[3]gets(c);puts(c);我输入了好几十个字符,本来以为会出现溢出之类的错误,但是还是可以原样输出,难道数组的长度没有用吗?不会溢出吗?... 我定义
char c[3]
gets (c);
puts(c);
我输入了好几十个字符,本来以为会出现溢出之类的错误,但是还是可以原样输出,难道数组的长度没有用吗?不会溢出吗?
展开
 我来答
百度网友657978d
推荐于2017-09-28 · TA获得超过197个赞
知道答主
回答量:85
采纳率:100%
帮助的人:20.3万
展开全部

  数组的长度当然有用了。你给数组指定多大,这里就的字符串长度容纳量就是多大。

  越界访问是语言的未定义行为,不能依赖于这种行为。(即使看起来有时候它不出错)

  你这里程序没有出现问题,仅仅是巧合而已。具体什么时候溢出会影响程序执行,取决于平台和编译器实现。

  打个比方,如果有个变量紧跟在数组后面,数组越界了,那么这个变量就会被改变。


  我给一个例子:

#include <stdio.h>

int main(int argc, char *argv[])
{
    char str[3];
    char c = 'x';
    printf("Key in str: ");
    gets(str);
    printf("str = %s, c = %c\n", str, c);
    return 0;
}


  我使用 64 位 Linux 编译运行的结果如图。若看不清楚请右键点开原图。

  左下角窗口显示了执行情况:

  第一次,我输入了16个字符,结果和 str 无关的 c 变成了 我输入末尾的 'F',这正是我输入的第 16 个字符(从零算是15)

  第二次,我输入了15个字符,结果 c 变成了 '\0',而C语言数组末尾的 '\0' 也是正是 str 的第 16 位,即 str[15] (下标从零开始)

  第三次,我输了 14 个字符,加上末尾的 \0 是 15 个。此时 c 没有被改变,仍然是 ‘x'.


  可以猜想。str 和 c 在内存上相差 15 个字节(因为 sizeof(char) 正好 1 字节)。


  把程序用 objdump 反汇编(右上窗口)。可以看出:

  movb $0x78, -0x1(%rbp) 这一句对应的就是 C 语言的 char c = 'x',  字符x 的 ascii 码是十六进制 78. 所以可以看出,c 的地址是 %rbp 寄存器储存量左移 0x1 字节,你可以理解成坐标为 -1;

  从 gets(str) 调用下面的汇编代码可以找到, 而 str 的地址为 %rbp 寄存器储存量左移 0x10 字节,也就是十进制的 -16。

  这二者正好相差 15, 验证了我们的猜想。


  纯手工码字截图,望采纳。

苑时芳扈戌
2019-12-06 · TA获得超过3.7万个赞
知道大有可为答主
回答量:1.2万
采纳率:29%
帮助的人:1017万
展开全部
gets遇到回车才会结束,puts遇到‘\0
’才会结束输出。
你定义char
c[3]
gets只管输入进去,puts
必须遇到
'\0'才会结束,而数组的最后一位才是
‘\0’
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式