C语言最全面的函数知识讲解!上万字纯干货!

本文详细介绍了C语言中的函数知识,包括库函数如gets、fgets、puts、fputs、strlen、strcat、strncat、strcmp等的使用,以及自定义函数和递归的应用。同时讨论了函数安全性和头文件的使用,强调了防止缓冲区溢出和使用fgets替代gets的重要性。还探讨了递归函数的优缺点,并提供了递归实例,如计算斐波那契数列。此外,文章还提到了多源文件程序的编译和头文件管理,以及如何避免重复包含的问题。
摘要由CSDN通过智能技术生成

涉及到的知识点有:

1、C语言库函数、字符输入函数:gets和fgets、字符输出函数:puts和fputs、

    求字符串长度函数strlen、字符串追加函数strcat、字符串有限追加函数strncat、字符串比较函数strcmp、

        字符串有限比较函数strcmp、字符串拷贝函数strcpy、字符串有限拷贝函数strncpy、

        格式化字符串函数sprintf(输出)、格式化字符串函数sscanf(读取输入)、解析一个字符串、

       字符串查找字符函数strchr、字符串查找子串函数strstr、字符串分割函数strtok、

       atoi函数、atof函数、atol函数、解析一个字符串的高级应用。

2、函数的定义和声明、函数的形式参数(形参)与实际参数(实参)、函数的返回值类型和返回值、

     return函数与exit函数(exit更猛,不受位置限制)、自定义一个函数,实现大小写字母的互相转换功能、

     自定义一个函数,实现atoi的功能。

3、函数的递归、递归例子:有n个人排成一队、递归例子:将10进制数转化为二进制数、

     递归例子:将10进制数转化为16进制、递归例子:菲波那切数列、递归的优点与缺点。

4、多个源代码文件程序如何编译、头文件的使用、解决预编译时会出现多次函数声明问题。

“我是一名从事了10年开发的老程序员,最近我花了一些时间整理关于C语言、C++,自己有做的材料的整合,一个完整的学习C语言、C++的路线,学习材料和工具。C/C++、编程爱好者的聚集地就在我这里 企鹅进<C语言C++编程学习>!欢迎初学和进阶中的小伙伴。希望你也能凭自己的努力,成为下一个优秀的程序员。工作需要、感兴趣、为了入行、转行需要学习C/C++的伙伴可以跟我一起学习!”

=============================================================================

C语言库函数

1、字符串处理函数:字符输入函数和字符输出函数

字符输入函数:gets和fgets

通过scanf输入的时候,最后按的是一个什么键?答:回车键,scanf会把回车键认为是输入完成,而不是字符串的内容。

而且scanf认为回车和空格都代表输入完成哦。

当字符数组的成员数量小于用户在键盘输入字符的数量之后,scanf并不会自动处理,而是把用户输入的所有字符都放入了数组,导致了数组溢出了,内存出错,程序崩溃。

-----------------------------------------------------------------------------

gets认为只有回车代表输入完成,空格只是字符串中的一部分而已。

gets和scanf一样有缓冲区溢出的危险。

-----------------------------------------------------------------------------

字符数组 的英文名字是 char []

gets()函数的基本用法为:

char *gets(char *s); 

该函数的参数是一个字符数组,该函数的返回值也是一个字符数组。

linux下示例代码如下:

1 #include

3 int main()

4 {

5    char a[100] = { 0 };

6    gets(a);

7    printf("%s\n", a);

8    return 0;

9 }

-----------------------------------------------------------------------------

编译时会出现一个warning,建议我们不要使用gets函数了。我们暂时不管他,先直接运行看结果。

--------------------------------------

警告如下:

a2.c:6:5: warning: implicit declaration of function ‘gets’ [-Wimplicit-function-declaration]

gets(a);

^

/tmp/cceyMQ7u.o: In function `main':

a2.c:(.text+0x41): warning: the `gets' function is dangerous and should not be used.

--------------------------------------

原因:

问题出在程序中使用了 gets是非常不安全的。这是对程序产生BUG,出现不可靠性的一个描述,

有些函数在某些意外情况会导致程序陷入不可控状态,仅仅是PC上运行最多也就是退出而已,

但是如果是运行在飞机等系统里的话,就会有大麻烦,说危险也不为过。因为英文文献里描述为dangerous,所以也就翻译为危险。

函数执行需要一个栈空间,但这个栈空间容量是有限的,而且栈里存放了函数返回的地址。

gets()函数在获取输入时,如果无限输入会造成栈空间溢出,在程序返回时,不能正常的找到返回地址,程序将发生不可预测行为。

--------------------------------------

解决:

解决办法是使用 fgets,但由于fgets函数是为读取文件设计的,所以读取键盘是没有gets那么方便。

fgets(char *s, int size, FILE *stream);

第一个参数是:字符类型的数组,第二个参数是:标明这个数组的大小,第三个参数是:如果总是通过键盘输入的话,可以固定写为stdin。

fgets()函数的基本用法为:

-------------------------------------

示例程序:

/*代码实现01_使用fputs函数打印输出*/

#include <stdio.h>

int main ( ) 

{

char name[20] = { 0 };

fgets(name, sizeof(name), stdin);//stdin 意思是键盘输入

fputs(name, stdout); //stdout 意思是通过打印设备输出

return 0;

}

--------------------------------------

/*代码实现02_使用printf函数打印输出*/

#include

int main ( ) 

{

char name[20] = { 0 };

fgets(name, sizeof(name), stdin);//stdin 意思是键盘输入

printf("%s", name);//这边输出不需要 \n 了,实际操作时,fgets会认为用户输入的回车也是字符串的一部分内容。即输出的内容中间接地带了 \n 了。

return 0;

}

-----------------------------------------------------------------------------

fgets会认为用户输入的回车也是字符串的一部分内容。

fgets是安全的,不会因为用户恶意的输入过长的字符串导致溢出。因为它只接受它能存的最大的字符数,其余的舍掉!

=============================================================================

字符输出函数:puts和fputs

puts函数打印字符串时,与printf不同,puts会在最后自动增加一个换行字符 '\n'。

puts不支持各种转义字符,如%d,%s都不支持,puts只能简单直接地输出一个字符串,而不能输出char类型(字符类型)、int类型(整型)、double类型(双精度浮点类型)等其他类型。

linux下示例代码如下:

1 #include

3 int main()

4 {

5   char a[] = "hello world";

6   puts(a);

7   return 0;

8 }

--------------------------------------

puts函数内部可能是如下这样实现的:

int puts(const char *s)

{

int index = 0;

while(s[index])

{

putchar(s[index]);

index++;

}

putchar('\n');

return index;

}

putchar函数的作用:向终端输出一个字符。

(1)putchar函数只能用于单个字符的输出,且一次只能输出一个字符。

(2)在程序中使用putchar函数,务必牢记:在程序(或文件)的开头加上编译预处理命令(也称包含命令),即:#include "stdio.h"。

//思考

用putchar就可以实现puts,printf等输出函数。

用getchar就可以实现scanf,gets等输入函数。

-----------------------------------------------------------------------------

fputs函数是puts函数的文件操作版本。

int fputs(const char *s, FILE *stream);  //注意:const用来修饰char *s, *s的内容不可变。

第一个参数是一个char的数组;第二个参数是:如果总是通过屏幕进行输出的话,可以固定写为stdout。

fputs并不会像puts那样输出的时候自动结尾加 \n 。

linux下示例代码如下:

1 #include

3 int main()

4 {

5    char a[] = "hello world"; 

6    //puts(a);       //hello world

//root@iZ2zeeailqvwws5dcuivdbZ:~/1/01#

7    //printf(a);         //hello worldroot@iZ2zeeailqvwws5dcuivdbZ:~/1/01# 编译有警告哦

8    fputs(a, stdout);  //hello worldroot@iZ2zeeailqvwws5dcuivdbZ:~/1/01#

9    return 0;

10 }

--------------------------------------

1 #include

3 int main()

4 {

5    char a[] = "hello world\n"; 

6    //puts(a); 

7    //printf(a);

8    fputs(a, stdout);  //hello world

9    return 0;        //root@iZ2zeeailqvwws5dcuivdbZ:~/1/01#

10 }

=============================================================================

求字符串长度函数strlen

使用这个库函数时需要包含头文件<string.h>

"abc",注意:用strlen时返回的结果是3,而不是4。

strlen函数的基本用法为:

size_t strlen(const char *s); 

参数是:一个字符数组。

返回值是:不包含字符串结尾'\0'的字符串的长度(注意:是字符串字节的总数哦!不同的系统下是不同的)。

linux下示例代码如下:

1 #include

2 #include

4 int main()

5 {

6    char a[] = "hello";//char a[] = "hello传智";

7    unsigned int index = 0;

8    /*

9    while (a[index])

10   {

11     index++;

12   }

13   */

14   index = strlen(a);

15      printf("%u\n",index);//5 //11

16   return 0;

17 }

=============================================================================

字符串追加函数strcat

strcat函数的基本用法为:

char *strcat(char *dest, const char *src);

参数是:第一个参数是一个字符数组,第二个参数是静态的字符数组。

返回值是:一个字符数组。

用strcat的时候要注意,第一个字符串一定要有足够的空间容纳第二个字符串。

linux下示例代码如下:

1 #include

2 #include

4 int main()

5 {

6    char a[100] = "abc";   //a不是空串时

7    char b[100] = "hello";

8    strcat(a,b);       //将a和b合并为一个字符串,合并的结果放入a。

9    printf("%s\n", a);  //abchello

10    return 0;

11 }

-----

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值