C语言的库函数、自定义函数、嵌套函数,以及递归函数

        函数是C语言和C++很重要的部分,从它们本身有的系统的库函数,到我们自定义类型的函数。我们需要了解进一步地了解它们,掌握它们,使用它们。

目录

库函数

常见的库函数

自定义函数

1.自定义取最大值得函数:

2.自定义取最小值的函数:

3.交换两数值

函数的调用

1.判断100-200之间素数

2.判断闰年

3.整型有序二分查找

传址

函数的嵌套调用和链式访问

嵌套调用

链式访问

函数的声明与定义

函数

函数递归

递归定义

递归的两个必要条件

练习1 打印无符号整型值

栈溢出实例

练习2 求字符串的长度

练习3 n的阶乘

练习4 求第n个斐波那契数

汉诺塔问题

台阶问题(费波纳西级数)


 

库函数

为什么会有库函数? 1.们知道在我们学习C语言编程的时候,总是在一个代码编写完成之后迫不及待的想知道结果,想把这个结果打印到我们的屏幕上看看。这个时候我们会频繁的使用一个功能:将信息按照一定的格式打印到屏幕上(printf)。 2.在编程的过程中我们会频繁的做一些字符串的拷贝工作(strcpy)。 3.在编程是我们也计算,总是会计算n的k次方这样的运算(pow)。

超级有用的网站工具https://zh.cppreference.com/w/%E9%A6%96%E9%A1%B5

内容比较齐全,可以进行搜索和学习。

常见的库函数

IO函数printf scanf getchar putchar
字符串操作函数strcmp strlen
字符操作函数toupper
内存操作函数memcp memset
时间/日期函数time
数学函数sqrt pow
其它库函数

1.pow()函数

pow() 函数用来求 x 的 y 次幂(次方),x、y及函数值都是double型

pow()用来计算以x 为底的 y 次方值,然后将结果返回。如下式:

#include<stdio.h>
#include<math.h>
int main()
{
    int x = 2;
    int y = 4;
    int m;
    m = pow(x,y);
    printf("%d",m);
    return 0;
}
输出:16

2.strcpy()函数

strcpy()函数是用来拷贝字符串的

#include<stdio.h>
#include<string.h>
int main()
{
    char arr1[20] = { 0 };
    char arr2[] = "hello bit";
    strcpy(arr1,arr2);
    printf("%s",arr1);
    return 0;
}
输出:hello bit
#include<stdio.h>
#include<string.h>
int main()
{
    char arr1[1] = { 0 };
    char arr2[] = "hello bit";
    strcpy(arr1,arr2);
    printf("%s",arr1);
    return 0;
}
输出:hello bit

发现字符串内容和数组arr[20/1]无关,甚至[]可以为空,当然里面不可以为0,否则会报错。

3.memset()函数

memory - 记忆 - 内存
memset - 内存设置
void *memset (void *ptr,int value,size_t num )
*ptr指的是要填充的字符块,是一个指针
value指的是被设置的值
num指的是num个字节的意思
#include<stdio.h>
#include<string.h>
int main()
{
    char arr[] = "hello bit";
    memset(arr,'x',5);
    printf("%s",arr);
    return 0;
}

通过这个函数的使用,我们将字符串中的部分字符替换掉了。

注意

·C语言中的单引号''用来表示字符的字面量

·C语言中的双引号""用来表示字符串的字面量

'a'表示字符字面量,在内存中占1个字节,'a'+1表示'a'在ASCLL码值中的大小加一,从而变成'b'

"a"表示字符串字面量,在内存中占2个字节,"a"+1表示指针运算,结果是指向"a"的结束符'\0'

·C语言中的单中括号[]和双中括号[[]]

size_t 是无符号整型unsigned int

自定义函数

自定义函数和库函数一样,有函数名,返回值类型和函数参数。但是不一样的是这些都是我们自己来设计。这给程序员一个很大的发挥空间。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
int main()
{
    char arr1[20] = { 0 };
    char arr2[] = "abc";
    strcpy(arr1, arr2);
    printf("%s\n",arr1);
    return 0;
}

利用strcpy()函数,我们能成功复制“abc”到arr1[]中去,这是库函数的方式

函数的组成:

ret_type fun_name(para1, *) 
{
 statement;//语句项
 } 
ret_type 返回类型
 fun_name 函数名
 para1 函数参数
 {}及内部所有内容都叫函数体

1.自定义取最大值得函数:

#include<stdio.h>
get_max(int x,int y)
{
    int z = 0;
    if(x > y)
        z = x;
    else z = y;
    return z;
}
int main()
{
    int a = 10;
    int b = 20;
    int max = get_max(a,b);//a和b就是传输上去的函数
    printf("max = %d\n",max);
    return 0;
}

2.自定义取最小值的函数:

依葫芦画瓢:

#include<stdio.h>
get_min(int x,int y)
{
    int z = 0;
    if(x < y)
        z = x;
    else z = y;
    return z;
}
int main()
{
    int a = 10;
    int b = 20;
    int min = get_min(a,b);
    printf("min = %d\n",min);
    return 0;
}

3.交换两数值

#include<stdio.h>
Swap(int a,int b)
{
    int z;
    z = a;
    a = b;
    b = z;
    printf("a=%d b=%d",a,b);
}
int main()
{
    int a = 10;
    int b = 20;
    printf("a=%d b=%d\n",a,b);
    Swap(a,b);
    return 0;
}

视频主要介绍下面代码和修改

#include<stdio.h>
void Swap(int a,int b)//void,表示这个函数不需要返回任何值
{
    int z;
    z = a;
    a = b;
    b = z;
}
int main()
{
    int a = 10;
    int b = 20;
    printf("a=%d b=%d\n",a,b);
    Swap(a,b);
    printf("a=%d b=%d\n",a,b);
    return 0;
}

这个的输出是有问题的,我们可以看到结果根本没有交换。这是因为自定义的函数是定义了另外两个值,地址是不一样的,最后输出的地址并不是自定义函数的地址。这时,我们需要用指针来指定地址。

首先我们来验证一下指针:

#include<stdio.h>
int main()
{
    int a = 10;
    int* pa = &a;
    *pa = 20;
    printf("%d",a);
    return 0;
}
输出结果:20

因此,我们接下来就可以将指针的知识运用到本题目之中。

#include<stdio.h>
void Swap(int* pa,int* pb)
{
    int z;
    z = *pa;
    *pa = *pb;
    *pb = z;
}
int main()
{
    int a = 10;
    int b = 20;
    printf("a=%d b=%d\n",a,b);
    Swap(&a,&b);
    printf("a=%d b=%d\n",a,b);
    return 0;
}

概念明晰

Swap1(a,b);
printf("交换前: a=%d b=%d\n",a,b);
Swap2(&a,&b);
printf("交换后: a=%d b=%d\n",a,b);
//上述两种函数在主函数内部的,函数调用均属于实际参数(实参)
​
void Swap1(int x,int y)
{
    int z = 0;
    z = x;
    x = y;
    y = z;
}
void Swap2(int x,int y)
{
    int z = 0;
    z = x;
    x = y;
    y = z;
}
void Swap2(int* pa,int* pb)
{
    int z = 0;
    z = *pa;
    *pa = *pb;
    *pb = z;
}
//上述的自定义函数则是属于形式参数(形参)

实际参数(实参): 真实传给函数的参数,叫实参。实参可以是:常量、变量、表达式、函数等。无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。 形式参数(形参): 形式参数是指函数名后括号中的变量,因为形式参数只有在函数被调用的过程中才实例化(分配内存单元),所以叫形式参数。形式参数当函数调用完成之后就自动销毁了。因此形式参数只在函数中有效。

#include<stdio.h>
Swap(int a,int b)
{
    int z;
    z = a;
    a = b;
    b = z;
    printf("a=%d b=%d\n",a,b);
}
int main()
{
    int a = 10;
    int b = 20;
    int c = 30;
    int d = 40;
    Swap(a,b);
    Swap(c,d);
    return 0;
}//主函数可以多次调用形参函数

函数的调用

传值调用 函数的形参和实参分别占有不同内存块,对形参的修改不会影响实参。 传址调用 传址调用是把函数外部创建变量的内存地址传递给函数参数的一种调用函数的方式。

这种传参方式可以让函数和函数外边的变量建立起正真的联系,也就是函数内部可以直接操作函数外部的变量。

1.判断100-200之间素数

#include<stdio.h>
#include<math.h>
int is_prime(int n)
{
    for(int j = 2;j < n;j++)
    {
        if(n % j == 0)
            return 0;
    }
    return 1;
}
int main()
{
    int i =0;
    int count = 0;
    for(i = 100;i <= 200; i++)
    {
    //判断i是否为素数
        if (is_prime(i) == 1)
        {
            printf("%d ",i);
            count++;
        }
    }
    printf("总共%d个素数",count);
    return 0;
}
#include<stdio.h>
#include<math.h>
int is_prime(int n)
{
    for(int j = 2;j <= sqrt(n);j++)
    {
        if(n % j == 0)
            return 0;
    }
    return 1;
}
int main()
{
    int i =0;
    int count = 0;
    for(i = 100;i <= 200; i++)
    {
    //判断i是否为素数
        if (is_prime(i) == 1)
        {
            printf("%d ",i);
            count++;
        }
    }
    printf("总共%d个素数",count);
    return 0;
}
输出:101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199 总共21个素数

2.判断闰年

#include<stdio.h>
int is_leap_year(int n)
{
    if((n % 4 == 0&& n % 100 != 0) || (n % 400 == 0) )
        return 1;
    else return 0;
}
int main(){
    int year;
    scanf("%d",&year);
    if(is_leap_year(year) == 1)
    {
        printf("是闰年");
    }
    else printf("不是闰年");
    return 0;
}

3.整型有序二分查找

#include<stdio.h>
int binary_search(int a[],int k,int s)
{
    int left = 0;
    int right = s - 1;
    while(left <= right)
    {
        int mid = (left + right) / 2;
        if(a[mid] > k)
        {
            right = mid - 1;
        }
        else if(a[mid] < k)
        {
            left = mid + 1;
        }
        else
        {
            return mid;
        }
    }  
    return -1;
}
int main()
{
    int arr[] = {1,2,3,4,5,6,7,8,9,10};
    int key;
    int sz = sizeof(arr) / sizeof(arr[0]);
    scanf("%d",&key);//找到就返回找到位置的下标
                     //找不到就输出-1
                     //数组arr传参,实际传输的不是数字本身
                     //仅仅传输过去了数组首元素的地址
    int ret = binary_search(arr,key,sz);
    if(-1 == ret)
    {
        printf("找不到\n");
    }
    else
    {
        printf("找到了,下标为:%d\n",ret);
    }
    return 0;
}

传址

#include<stdio.h>
void Add(int*p)
{
    (*p)++;
}
int main()
{
    int num = 0;
    Add(&num);
    printf("%d\n",num);
    Add(&num);
    printf("%d\n",num);
    Add(&num);
    printf("%d\n",num);
    Add(&num);
    printf("%d\n",num);
    return 0;
}
输出:1
     2
     3
     4//传址

函数的嵌套调用和链式访问

嵌套调用

嵌套调用就是某个函数调用另外一个函数(即函数嵌套允许在一个函数中调用另外一个函数)。

#include<stdio.h>
int test1()
{
    test2();
    return 0;
}
void test2()
{
    printf("Hello\n");
}
int main()
{
    test1();
    return 0;
}//嵌套调用

链式访问

链式访问其实就是将两个或多个结构像链子一样关联起来,A可以通过链子的方向找到B的所在地,B也可以通过链子反向找到A。

#include<stdio.h>
#include<string.h>
int main()
{
    int len = strlen("abc");
    printf("%d\n",len);
    
    //链式访问
    printf("%d\n",strlen("abc"));
    
    char arr1[20] = { 0 };
    char arr2[] = "bit";
    printf("%s\n",strcpy(arr1,arr2));
    return 0;
}

Return Value

#include<stdio.h>
int main()
{
    printf("%d",printf("%d",printf("%d",43)));
    return 0;
}
输出结果:4321

//函数返回的是打印在屏幕上的字符的个数,所以上式就是先输出43,然后输出2(代表43两个字符个数),最后输出1(代表2一个)。

函数顺序

#include<stdio.h>
int main()
{
    int a = 10;
    int b = 20;
    //函数声明
    int Add(int, int);
    int c = Add(a,b);
    printf("%d",c);
    return 0;
}
//函数定义
int Add(int x,int y)
{
    return x + y;
}
#include<stdio.h>
//函数定义
int Add(int x,int y)
{
    return x + y;
}
int main()
{
    int a = 10;
    int b = 20;
    //函数声明
    //int Add(int, int);这个函数需要再定义。
    int c = Add(a,b);
    printf("%d",c);
    return 0;
}

函数要先定以后声明

函数的声明与定义

函数的声明和定义 函数声明: 1.告诉编译器有一个函数叫什么,参数是什么,返回类型是什么。但是具体是不是存在,无关紧要。 2.函数的声明一般出现在函数的使用之前。要满足先声明后使用。 3.函数的声明一般要放在头文件中的。 函数定义: 函数的定义是指函数的具体实现,交待函数的功能实现。 test.h的内容放置函数的声明

#ifndef _TEST_H_
#define _TEST_H_
//函数的声明
int Add(int x,int y);
#endif //TEST_H_

比如说:

A  -  加法    add.h   add.c
B  -  减法    sub.h   sub.c
C  -  乘法
D  -  除法
<main.h>//头文件
#define _CRT_SECURE_NO_WARNING 1
​
int Add(int x,int y);
<main.c>
#include<stdio.h>
int main()
{
    int a = 10;
    int b = 20;
    //函数声明
    int Add(int, int);
    int c = Add(a,b);
    printf("%d",c);
    return 0;
}
//函数定义
int Add(int x,int y)
{
    return x + y;
}
#include<stdio.h>
#include "main.c"//引用函数
int main()
{
    int a = 10;
    int b = 20;
    int c = Add(a,b);
    printf("%d\n",c);
    return 0;
}

函数

函数递归

递归定义

程序调用自身的编程技巧称为递归(recursion)。递归做为一种算法在程序设计语言中广泛应用。一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。递归的主要思考方式在于:把大事化小。

递归的两个必要条件

·存在限制条件,当满足这个限制条件的时候,递归便不再继续。 ·每次递归调用之后越来越接近这个限制条件。

练习1 打印无符号整型值

接受一个整型值(无符号),按照顺序打印它的每一位。例如:输入:1234,输出1 2 3 4(用递归完成)

#include<stdio.h>
void print(unsigned int n)
{
    if(n > 9)
    {
        print(n / 10);
    }
    printf("%d ",n % 10);
}
int main()
{
    unsigned int num;
    scanf("%u",&num);//%u是无符号整型
    print(num);
    return 0;
}
//print(1234)
  print(123) 4
  print(12) 3 4
  print(1) 2 3 4

栈溢出实例

#include<stdio.h>
void test(int n)
{
    if(n < 10000)
    {
        test(n + 1);
    }
}
int main()
{
    test(1);
    return 0;
}//发生死循环

原理:

栈区:局部变量 函数形参 //储存临时

堆区:动态内存分配 malloc / free / realloc

静态区:全局变量 静态变量

test
test
内存栈区test
test
test
main 的栈帧空间

但凡test过多,就会导致栈内存不够,必然会溢出,死循环。

写递归代码的时候:

1.不能死递归,都有跳出条件,每次递归逼近跳出条件

2.递归层次不能太深

网站推荐:www.stackoverflow.con

练习2 求字符串的长度

编写函数,不允许创建临时变量,求字符串的长度。

原先求字符串长度的代码如下:

#include<stdio.h>
#include<string.h>
int main()
{
    char arr[] = {};
    scanf("%s",&arr);
    //比如说['a']['b']['c']['d']
    printf("%d\n",strlen(arr));
    return 0;
}

模拟实现一个strlen函数

#include<stdio.h>
#include<string.h>
int my_strlen(char* str)
{
    int count;
    while(*str != '\0')
    {
        count++;
        str++;
    }
    return count;
}
int main()
{
    char arr[] = {};
    scanf("%s",&arr);
    printf("%d\n",my_strlen(arr));
    return 0;
}

但是count就是创建出来的临时变量,所以该写法需要改正的。

#include<stdio.h>
#include<string.h>
int my_strlen(char* str)
{
    if(*str != '\0')
        return 1 + my_strlen(str+1);
    //return 1 + my_strlen(str++)//str后置是不行的,就把原来的str替换掉了
    //return 1 + my_strlen(++str)//str前置是可以的
}
int main()
{
    char arr[] = {};
    scanf("%s",&arr);
    printf("%d\n",my_strlen(arr));
    return 0;
}

本题的递归思路

比如输入了 bit。

my_strlen("bit")/一次输入头一个字符,可识别第一个; 1+my_strlen("it"); 1+1+my_strlen("t") 1+1+1+my_strlen();//碰到'\0'就会停止; 1+1+1+0=3

练习3 n的阶乘

求n的阶乘(不考虑溢出)

#include<stdio.h>
int main()
{
    int n,ret = 1;
    scanf("%d",&n);
    for(int i = 1;i <= n; i++)
    {
        ret = ret * i;
    }
    if(n == 0)
    {
        printf("1");
    }
    return 0;
}
#include<stdio.h>
int Fac(int n)
{
    if(n <= 1)
        return 1;
    else 
        return n * Fac(n - 1);
}
int main()
{
    int n;
    scanf("%d",&n);
    int ret = Fac(n);
    printf("%d",ret);
    return 0;
}

通常能用循环迭代的函数可以调用递归。

练习4 求第n个斐波那契数

#include<stdio.h>
int Fib(int n)
{
    if(n <= 2)
    {
        return 1;
    }
    else 
        return Fib(n - 1) + Fib(n - 2);
}
int main()
{
    int n;
    scanf("%d",&n);
    int ret = Fib(n);
    printf("%d",ret);
    return 0;
}

递归缺点:效率太低 —重复大量的计算,而且过大就会突破int的上限。

#include<stdio.h>
int main()
{
    int n,a=1,b=1,c=1;
    scanf("%d",&n);
    while(n > 2)
    {
        c = a + b;
        a = b;
        b = c;
        n--;
    }
    printf("%d",c);
    return 0;
}

汉诺塔问题

汉诺塔(Tower of Hanoi),又称河内塔。源自印度古老传说的一个游戏,大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。

若只有1个圆盘时,需要移动1次;若有2个圆盘时,需要移动3次;若有3个圆盘时,需要移动7次……不难看出,汉诺塔步数的数学规律为2的n次方减1(n为柱子上的圆盘个数)。所以若有64个圆盘那将会移动2^64-1次(即:18,446,744,073,709,551,615‬次)

#include<stdio.h>
int count = 0;
void move(char A, char C, int n)
{
    count++;
}
​
void HanoiTower(char A, char B, char C, int n)
{
    if (n == 1)
    {
        move(A, C, n);
    }
    else
    {
        //将n-1个圆盘从A柱借助于C柱移动到B柱上
        HanoiTower(A, C, B, n - 1);
        //将A柱子最后一个圆盘移动到C柱上
        move(A, C, n);
        //将n-1个圆盘从B柱借助于A柱移动到C柱上
        HanoiTower(B, A, C, n - 1);
    }
}
​
int main()
{
    //输入移动的个数
    int n;
    scanf("%d",&n);
    //将n个圆盘从A柱借助于B柱移动到C柱上
    HanoiTower('A', 'B', 'C', n);
    printf("%d",count);
    return 0;
}

台阶问题(费波纳西级数)

一次可以上1个台阶,也可以上2个台阶,n个台阶有多少种跳法。

#include <stdio.h>

int fib(n)
{
	if (n == 1)//限制条件
		return 1;
	else if (n == 2)//限制条件
		return 2;
	else
		return fib(n - 1) + fib(n - 2);//关键变量n的变化
}

int main()
{
	int n = 0;
	scanf("%d", &n);

	int sum = fib(n);
	printf("%d", sum);
	return 0;
}
```

最后的最后,是我总结课程的各种函数所实现的,大家可以自取!!!!!

常见的库函数

1.pow()函数

pow() 函数用来求 x 的 y 次幂(次方),x、y及函数值都是double型

pow()用来计算以x 为底的 y 次方值,然后将结果返回。如下式:

#include<stdio.h>
#include<math.h>
int main()
{
    int x = 2;
    int y = 4;
    int m;
    m = pow(x,y);
    printf("%d",m);
    return 0;
}
输出:16

2.strcpy()函数和strncpy()函数

strcpy()函数是用来拷贝字符串的

#include<stdio.h>
#include<string.h>
int main()
{
    char arr1[20] = { 0 };
    char arr2[] = "hello bit";
    strcpy(arr1,arr2);
    printf("%s",arr1);
    return 0;
}
输出:hello bit
#include<stdio.h>
#include<string.h>
int main()
{
    char arr1[1] = { 0 };
    char arr2[] = "hello bit";
    strcpy(arr1,arr2);
    printf("%s",arr1);
    return 0;
}
输出:hello bit

发现字符串内容和数组arr[20/1]无关,甚至[]可以为空,当然里面不可以为0,否则会报错。

strncpy函数用于将指定长度的字符串复制到字符数组中,是 C语言的库函数之一,来自 C语言标准库,定义于 string.h。语法形式为:char *strncpy(char *dest, const char *src, int n),表示把src所指向的字符串中以src地址开始的前n个字节复制到dest所指的数组中,并返回被复制后的dest

#include<stdio.h>
#include<string.h>
int main()
{
    char ch1[] = "************";
    char ch2[] = "hello bit";
    strncpy(ch1,ch2,7);
    printf("%s\n",ch1);
    return 0;
}
输出:hello b*****

3.memset()函数

memory - 记忆 - 内存
memset - 内存设置

void *memset (void *ptr,int value,size_t num )
*ptr指的是要填充的字符块,是一个指针
value指的是被设置的值
num指的是num个字节的意思
#include<stdio.h>
#include<string.h>
int main()
{
	char arr[] = "hello bit";
	memset(arr,'x',5);
    printf("%s",arr);
	return 0;
}
xxxxx bit

通过这个函数的使用,我们将字符串中的部分字符替换掉了。

注意

·C语言中的单引号''用来表示字符的字面量

·C语言中的双引号""用来表示字符串的字面量

'a'表示字符字面量,在内存中占1个字节,'a'+1表示'a'在ASCLL码值中的大小加一,从而变成'b'

"a"表示字符串字面量,在内存中占2个字节,"a"+1表示指针运算,结果是指向"a"的结束符'\0'

·C语言中的单中括号[]和双中括号[[]]

size_t 是无符号整型unsigned int

4.strcpy()函数和strncpy()函数

strcpy是用来字符串拷贝的

#include<stdio.h>
#include<string.h>
int main()
{
    char arr[] = "xxxxxxxxx";
    char arr2[] = "hello";
    strcpy(arr,arr2);
    printf("%s",arr);
    return 0;
}

strcpy(arr,arr2); 这样就能把arr2里面的字符串拷贝到arr中去了

这个库函数,其实返回的是目标空间的起始地址

#include<stdio.h>
#include<string.h>
int main()
{
    char arr1[] = "hello ";
    strncat(arr1,arr1,10);//字符串自身追加(连接)
    printf("%s",arr1);
    return 0;
}
hello hello hell

5.strcat()函数和strncat()函数

strcat是用来连接两个字符串的,原型是char *strcat(char *dest,char *src),作用是把src所指字符串添加到dest结尾处

#include<stdio.h>
#include<string.h>
int main()
{
    char arr[] = "hello ";
    strcat(arr,"bit");
    printf("%s\n",arr);
    return 0;
}

strncat()主要功能是在字符串的结尾追加n个字符。原型是charstrncat(char dest,const char*src,size_t n)

如果要追加本身,就用如下方式

#include<stdio.h>
#include<string.h>
int main()
{
    char arr[] = "hello ";
    strncat(arr,arr,4);//区别strncat和strcat
    printf("%s\n",arr);
    return 0;
}
hello hell

6.strstr()函数

strstr(str1,str2) 函数用于判断字符串str2是否是str1的子串。如果是,则该函数返回 str1字符串从 str2第一次出现的位置开始到 str1结尾的字符串;否则,返回NULL。

#include<stdio.h>
#include<string.h>
int main()
{
    char ch1[] = "ABCDEFGHI";
    char ch2[] = "BCD";
    char* ret = strstr(ch1,ch2);
    if(ret != NULL)
    {
        printf("Yes");
    }
    else printf("No");
    return 0;
}

7.strcmp()函数

#include<stdio.h>
#include<string.h>
int main()
{
    char ch1[] = "obc";
    char ch2[] = "abcdef";
    int ret = strcmp(ch1,ch2);//字符串比较
    if(ret == 0)
    {
        printf("相等");
    }
    else printf("不相等");
    return 0;
}

8.strtok()函数

用于切割字符串

include<stdio.h>
#include<string.h>
int main()
{
    char arr[] = "3090378834@.qq.com";
    char* p = "@.";
    char tmp[20] = { 0 };
    strcpy(tmp, arr);
    char* str = strtok(tmp, p);
    printf("%s\n",str);
    str = strtok(NULL, p);//明确看出有三段所以调用三次
    printf("%s\n",str);
    str = strtok(NULL, p);
    printf("%s\n",str);
    return 0;
}
3090378834//这是我的qq,有兴趣的老铁可以加哦
qq
com

9.strerror()函数

返回错误码,所对应的错误信息

char* strerror(int errnum);
#include<stdio.h>
#include<string.h>
#include<errno.h>
int main()
{
    printf("%s\n",strerror(0));
    printf("%s\n",strerror(1));
    printf("%s\n",strerror(2));
    printf("%s\n",strerror(3));
    printf("%s\n",strerror(4));
    printf("%s\n",strerror(5));
    printf("%s\n",strerror(6));
    return 0;
}
No error
Operation not permitted
No such file or directory
No such process
Interrupted function call
Input/output error
No such device or address

调用失败查看原因

#include<stdio.h>
#include<string.h>
#include<errno.h>
int main()
{
    FILE* pf = fopen("test.txt","r");
    if(pf == NULL)
    {
        printf("%s\n",strerror(errno));
        return 1;
    }
    //……
    fclose(pf);
    pf = NULL;
    return 0;
}
No such file or directory

 

  • 24
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Williamtym

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值