由入门C语言题目浅析gets()函数的用法

一、背景

当执行下面的程序时,如果输入ABC,则
知输出结果是()
#include<stdio.h>
#include<string.h>
int main()
{
char ss[10] = “1,2,3,4,5”;
gets(ss);strcat(ss,“6789”);
printf("%s\n",ss);
return 0;
}

在逛论坛的时候遇到了如上的一个问题,目测应该是二级题库或者水平考试的题目,
题目本身不难,我也顺手给坛友回复了自己的看法:
在这里插入图片描述
没曾想这个问题还没有结束…

在这里插入图片描述
那么该怎么科学认识gets()这个函数呢?

二、曲径探幽

1. 贫穷的困扰

根据学Python学Java的经验,遇到问题,最简单的解决办法是查阅官方文档。

让我们来找找C语言的官方文档;
在这里插入图片描述
哦?
在这里插入图片描述
点进去看看
在这里插入图片描述
在这里插入图片描述
贫穷是阻碍不了我们追求知识的,
既然没有免费的官方标准文档,
我们也不到处去找一些第三方文档了,
让我们自己来分析一下子(要找也能找到,主要是为了引入下一段分析源码)
<本文发表于CSDN博客,由入门C语言题目浅析gets()函数的用法,https://blog.csdn.net/ftimes/article/details/106957922,转载请注明出处>

2. 奋斗本身是一种幸福

大大教育我们:“幸福是奋斗出来的,奋斗本身是一种幸福。”

虽然没有文档,但是我们可以看看网上免费的一些教程有个大概了解

在这里插入图片描述
有了这个文档,我们对gets有了大概了解,

下面我们需要自己奋斗一下,把握gets的一些特性

还是用刚刚的例子

在这里插入图片描述
在这里插入图片描述
可以看到,读入了一个新字符串之后,ss的地址是没有变的,并不是指向了一个新的字符串,
那么问题又来了,
abc是明显覆盖不了ss[10]的,那么其他位置的元素去哪里了呢?

我们来改一下代码:
用了一下C++,所以需要加点头文件

#include <bits/stdc++.h>
#include <iostream>
using namespace std;

#include<stdio.h>
#include<string.h> 
int main()
{
        char ss[10] = "12345";
        
        cout<<"org ss is :"<< &ss << endl;

        gets(ss);

        cout<<"now ss is :"<< &ss << endl;

        for (int i = 0; i < 10;++i)
        {
                cout << ss[i] ;
        }
        cout << endl;
        //strcat(ss,"6789");
        //printf("%s\n",ss);
        return 0;
}

输入abc,输出结果如图
在这里插入图片描述
在本来该存放“12345”的内存区域,变成了“abc 5”

看到这里,也许有朋友会问,不应该是"abc45"吗,为什么莫名多了一个空格?

当年学C的时候,学校老师就叮嘱我们一定要注意C-type字符串的结束符 ‘\0’
‘\0’标志着一个字符串的结束,
让我们输出一下’\0’的ASCII码验证一下

末尾加一行代码:

printf("%d", ss[3]);

在这里插入图片描述

自信输出ACII码为0,\0为占位符无疑

在这里,我们再来验证一下,字符数超过char ss[10]的情况

#include <bits/stdc++.h>
#include <iostream>
using namespace std;

#include<stdio.h>
#include<string.h> 
int main()
{
        char ss[10] = "123456789";
        
        cout<<"org ss is :"<< &ss << endl;

        gets(ss);

        cout<<"now ss is :"<< &ss << endl;

        for (int i = 0; i < 10;++i)
        {
                cout << ss[i] ;
        }
        cout << endl;
        //strcat(ss,"6789");
        //printf("%s\n",ss);
         printf("%d", ss[3]);
        return 0;
       
}

需要注意的是,由于需要一个结束符占位,所以ss[10]只能存到1-9
在这里插入图片描述
起始地址不变,原数组被覆盖。

三、总结一下

C-type的字符串ss,其实只是一个首地址,
我们用gets()输入数据,其实就是从字符串不断叠加,通过换行符终止之后,gets就自动加个’\0’标志字符串结束。
输出的时候,系统也是不断的顺着首地址读,读到结束符为止。

所以:

  1. 覆盖了原数据;
  2. 不受原数组大小限制;
  3. 不会指向一个新地址;

其实gets与scanf相比还有一些不同的特性,这里暂且不表,
表达能力有限,
祝大家端午安康,天天开心吧~!

在这里插入图片描述
感觉有用请点个赞哦~

猜你喜欢

转载自blog.csdn.net/ftimes/article/details/106957922