C语言总结_数组与函数传参练习题

385 阅读5分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

字符串标准处理函数介绍(string.h)、指针和数组当做函数形参,指针定义、函数返回指针、void类型定义指针、类型强制转换、常量声明、extern外边引用声明关键字。

1. 总结字符串相关的处理函数

string.h里常用的字符串处理相关函数。

 字符串: string.h
 void *memcpy(void *restrict, const void *restrict, size_t);
 int  memcmp(const void *, const void *, size_t);
 void *memset(void *, int, size_t);
 char *strcat(char *restrict, const char *restrict);
 int  strcmp(const char *, const char *);
 char *strcpy(char *restrict, const char *restrict);
 size_t strlen(const char *);
 char *strncat(char *restrict, const char *restrict, size_t);
 int  strncmp(const char *, const char *, size_t);
 char *strncpy(char *restrict, const char *restrict, size_t);
 char *strstr(const char *, const char *);
 ​
 格式化打印(转换)函数:
 int sprintf(char *str, const char *format, ...);
 int snprintf(char *str, size_t size, const char *format, ...);
 int sscanf(const char *str, const char *format, ...);

说明: char p; // a=aa; //乘法 char *p; //定义指针 指针用于代表一个地址。 指针可以当做数组使用,数组无法当做指针使用。

数组的名称: 就是首地址 在C语言里任何类型的指针(地址)是4个字节

2. 函数参数: 指针与数组类型

函数的形参: 指针类型与数组类型 示例代码: ()

 #include <stdio.h>  //标准输入输出
 #include <string.h> //字符串处理头文件
 int my_strlen1(char buff[]);
 int my_strlen2(char *buff);
 ​
 int main(int argc,char **argv)
 {
     char str[]="1234567890";
     int len1=my_strlen1(str);
     int len2=my_strlen2(str);
     printf("%d\n",len1);
     printf("%d\n",len2);
     return 0;
 }
 ​
 /*
 函数功能:计算字符串的长度
 char buff[] :传入是数组类型,也就是传入的是地址
 */
 int my_strlen1(char buff[])
 {
     int cnt=0;
     while(buff[cnt]!='\0')
     {
         cnt++;
     }
     return cnt;
 }
 ​
 /*
 函数功能:计算字符串的长度
 char *str :传入是字符指针类型,也就是传入的是地址
 */
 int my_strlen2(char *buff)
 {
     int cnt=0;
     while(buff[cnt]!='\0')
     {
         cnt++;
     }
     return cnt;
 }

3. 数组当做函数形参的问题

 示例:
 #include <stdio.h>  //标准输入输出
 #include <string.h> //字符串处理头文件
 ​
 void my_func1(char buff[100]);
 void my_func2(char *buff);
 void sum(int a);
 ​
 int main(int argc,char **argv)
 {
     int a=100;
     char str[100]="12345";
     my_func1(str);
     my_func2(str);
     sum(a);
     return 0;
 }
 ​
 //char buff[100] 函数形参里是地址不会申请空间
 void my_func1(char buff[100])
 {
     char buff1[100];
     printf("sizeof=%d\n",sizeof(buff));
     printf("sizeof1=%d\n",sizeof(buff1));
 }
 ​
 void my_func2(char *buff)
 {
     printf("sizeof=%d\n",sizeof(buff));
 }

4. 指针定义: 存放地址

 #include <stdio.h>  //标准输入输出
 #include <string.h> //字符串处理头文件
 ​
 int main(int argc,char **argv)
 {
     int a=100;
     char str[100]="123456";
     char *p; //定义的是一个指针(地址)
     p=str;   //可以赋值
     //p=&a;    //可以赋值
 ​
     printf("%p\n",&a);
     printf("%p\n",str);
     printf("%p\n",p);
     
     printf("%s\n",str);
     printf("%s\n",p);
     return 0;
 }

5. 函数形参和返回值: 都是地址

(1)数组类型可以当做函数形参。void func(char buff[]){}

(2)数组类型不能当做函数返回值类型。char buff[] func(void){} 错误的 函数如果要返回地址类型: 必须使用指针类型。 函数形参如果要传入地址类型: 可以使用指针类型或者数组类型。

示例代码:

 #include <stdio.h>  //标准输入输出
 #include <string.h> //字符串处理头文件
 char *func(char buff[]);
 int main(int argc,char **argv)
 {
     char str[]="12345";
     char *str1=func(str);
     
     printf("%p\n",str);
     printf("%p\n",str1);
     
     printf("%s\n",str1);
     return 0;
 }
 ​
 //形参是一个数组类型(char的地址)
 //返回值是一个char类型的地址
 char *func(char buff[])
 {
     return buff;
 }
 ​
 示例代码(局部地址是不能返回的)
 #include <stdio.h>  //标准输入输出
 #include <string.h> //字符串处理头文件
 char *func(void);
 int func1(void);
 int main(int argc,char **argv)
 {
     char *str=func();
     printf("str=%s\n",str);
     printf("str2=%p\n",str);
     
     int a=func1();
     printf("a=%d\n",a);
     return 0;
 }
 ​
 char *func(void)
 {
     char str[]="5thgtrgbtfbfgbgf";
     //static char str[]="5thgtrgbtfbfgbgf"; 
     //加了静态关键字之后,数据空间永久保留(与main函数生命周期一样)
     printf("str1=%p\n",str);
     return str; //将数据空间的地址返回,将地址赋值给接收返回值的指针变量
 }
 ​
 int func1(void)
 {
     int a=88;
     return a; //a变量里的数据取出来返回去,赋值给接收返回值的变量。
 }

6. void*类型指针

 #include <stdio.h>  //标准输入输出
 #include <string.h> //字符串处理头文件
 void func(void *p);
 ​
 int main(int argc,char **argv)
 {
     int buff[100];
     char str[100];
     func(buff);
     func(str);
     return 0;
 }
 ​
 /*
 void *p:传入的形参自适应
 */
 void func(void *p)
 {
     
 }
 //void a; //语法是错误的
 //int a;  //定义一个int类型变量,空间是4个字节
 //void *p //指针本身是存放地址,任何类型的指针都是4个字节

7. 强制转换

强制转换只是欺骗编译器,消除警告,不会改变本身的数据类型。 示例代码: 指针之间的强制转换

 #include <stdio.h>  //标准输入输出
 #include <string.h> //字符串处理头文件
 void func(int *p);
 ​
 int main(int argc,char **argv)
 {
     char str[]="123456789";
     func((int*)str); //强制转换语法
     return 0;
 }
 ​
 /*
 void *p:传入的形参自适应
 */
 void func(int *p)
 {
     char *str=(char*)p;
     printf("str=%s\n",str);
 }

8. 常量声明关键字: const

 #include <stdio.h>  //标准输入输出
 #include <string.h> //字符串处理头文件
 ​
 int main(int argc,char **argv)
 {
     char buff[100]="123";
     const char *p=buff; //表示p指向的buff的空间数据是不能修改的
     //*p='A'; //不能修改  赋值是错误的
     p[0]='A'; //不能修改  赋值是错误的
     
     //const int a=99;//定义a是只读变量。
     //a=88; //赋值是错误的
     return 0;
 }

9. extern外部声明关键字

 主要是用在头文件里,多文件编程中。
 #include <stdio.h>  //标准输入输出
 #include <string.h> //字符串处理头文件
 extern void func(void);//外部引用声明
 extern int data; //外部引用声明
 ​
 int main(int argc,char **argv)
 {
     func();
     printf("%d\n",data);
     return 0;
 }
 ​
 int data=888; //定义变量
 void func(void)
 {
     printf("123\n");
 }