C语言中的指针(指针,指针和数组、函数、字符串的交叉知识)--C语言07
C语言中的指针
说到指针不能不提一下内存
先概述一下
内存含义:存储器:计算机的组成中,用来存储程序和数据,辅助CPU进行运算处理的重要部分。
内存:内部存贮器,暂存程序/数据——掉电丢失 SRAM、DRAM、DDR、DDR2、DDR3。
外存:外部存储器,长时间保存程序/数据—掉电不丢ROM、ERRROM、FLASH(NAND、NOR)、硬盘、光盘。
内存是沟通CPU与硬盘的桥梁: 暂存放CPU中的运算数据,暂存与硬盘等外部存储器交换的数据
有关内存的两个概念:物理存储器和存储地址空间
物理存储器:实际存在的具体存储器芯片。主板上装插的内存条,显示卡上的显示RAM芯片,各种适配卡上的RAM芯片和ROM芯片都是物理存储器。
存储地址空间:对存储器编码的范围。我们在软件上常说的内存是指这一层含义。
编码:对每个物理存储单元(一个字节)分配一个号码
寻址:可以根据分配的号码找到相应的存储单元,完成数据的读写
内存地址:将内存抽象成一个很大的一维字符数组。编码就是对内存的每一个字节分配一个32位或64位的编号(与32位或者64位处理器相关)。这个内存编号我们称之为内存地址。
内存中的每一个数据都会分配相应的地址:char:占一个字节分配一个地址; int: 占四个字节分配四个地址; float、struct、函数、数组等
指针和指针变量
内存区的每一个字节都有一个编号,这就是“地址”。
如果在程序中定义了一个变量,在对程序进行编译或运行时,系统就会给这个变量分配内存单元,并确定它的内存地址(编号)
指针的实质就是内存“地址”。指针就是地址,地址就是指针。
指针是内存单元的编号,指针变量是存放地址的变量。
通常我们叙述时会把指针变量简称为指针,实际他们含义并不一样。
指针小结:(为了好找写这里了)
| 定义 | 说明 |
| int *p | 定义一个指向int的指针变量 |
| int *p[10] | 定义一个有10个元素的数组,每个元素类型为int* |
| int (*p)[10] | 定义包含有10个元素的数组指针(行指针) |
| int fun(){} | 定义一个函数,返回值为int型 |
| int *func(){} | 定义一个函数,返回值为int *型 |
| int (*fun) (int x); | 声明一个函数指针 |
| int **p | 定义一个指向int型数据的指针的指针,二级指针 |
一、指针基础知识
1、指针变量的定义和使用
指针也是一种数据类型,指针变量也是一种变量
指针变量指向谁,就把谁的地址赋值给指针变量
“*”操作符操作的是指针变量指向的内存空间
1 #include <stdio.h> 2 3 int main() 4 { 5 int a = 0; 6 char b = 100; 7 printf("%p, %p\n", &a, &b); //打印a, b的地址 8 9 //int *代表是一种数据类型,int*指针类型,p才是变量名 10 //定义了一个指针类型的变量,可以指向一个int类型变量的地址 11 int *p; 12 p = &a;//将a的地址赋值给变量p,p也是一个变量,值是一个内存地址编号 13 printf("%d\n", *p);//p指向了a的地址,*p就是a的值 14 15 char *p1 = &b; 16 printf("%c\n", *p1);//*p1指向了b的地址,*p1就是b的值 17 18 return 0; 19 }
注意:&可以取得一个变量在内存中的地址。但是,不能取寄存器变量,因为寄存器变量不在内存里,而在CPU里面,所以是没有地址的。
2、通过指针间接修改变量的值
1 #include <stdio.h> 2 3 int main() 4 { 5 int a = 0; 6 int b = 11; 7 int *p = &a; 8 9 *p = 100; 10 printf("a = %d, *p = %d\n", a, *p); 11 12 p = &b; 13 *p = 22; 14 printf("b = %d, *p = %d\n", b, *p); 15 16 return 0; 17 }
3、指针大小
使用sizeof()测量指针的大小,得到的总是:4或8
sizeof()测的是指针变量指向存储地址的大小
在32位平台,所有的指针(地址)都是32位(4字节)
在64位平台,所有的指针(地址)都是64位(8字节)
4、野指针和空指针
指针变量也是变量,是变量就可以任意赋值,不要越界即可(32位为4字节,64位为8字节)。但是任意数值赋值给指针变量没有意义,因为这样的指针就成了野指针,此指针指向的区域是未知(操作系统不允许操作此指针指向的内存区域)。所以,野指针不会直接引发错误,操作野指针指向的内存区域才会出问题。
注意:野指针和有效指针变量保存的都是数值,为了标志此指针变量没有指向任何变量(空闲可用),C语言中,可以把NULL赋值给此指针,这样就标志此指针为空指针,没有任何内存的指针。例如:int *p = NULL;
注意:NULL是一个值为0的宏常量,即:#define NULL ((void *)0)
5、万能指针void *
void *指针可以指向任意变量的内存空间
1 #include <stdio.h> 2 3 int main() 4 { 5 void *p = NULL; 6 7 int a = 1; 8 p = (void *)&a; //指向变量时,最好转换为void * 9 10 //使用指针变量指向的内存时,转换为int * 11 *( (int *)p ) = 11; 12 printf("a = %d\n", a); 13 14 return 0; 15 }
6、const修饰的指针变量
在编辑程序时,指针作为函数参数,如果不想修改指针对应内存空间的值,需要使用const修饰指针数据类型。
1 #include <stdio.h> 2 3 int main() 4 { 5 int a = 100; 6 int b = 200; 7 8 //指向常量的指针 9 //修饰*,指针指向的内存所存内容不能修改,指针指向内存地址可以变 10 const int * p1 = &a; //等价于int const *p1 = &a; 11 //*p1 = 111; //err 12 p1 = &b; //ok 13 14 //指针常量 15 //修饰p1,指针指向内存地址不能变,指针指向的内存所存内容可以修改 16 int * const p2 = &a; 17 //p2 = &b; //err 18 *p2 = 222; //ok 19 20 return 0; 21 }
二、指针和数组
明确一点:数组名字是数组的首元素地址,但它是一个常量,不能修改。
1、指针操作数组元素
1 #include <stdio.h> 2 /* 3 int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 4 a是数组第一个元素的地址,即a[0]的地址 5 int *p = a; 6 将a赋值给指针p(也可以说,定义一个指向a的指针p),那么p+1指向的就是第二个元素的地址,即a[1]的地址,以此类推。。。。。。 7 那么*P的值就是1,*(p+1)的值就是2,以此类推 8 */ 9 10 int main() 11 { 12 int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 13 int i = 0; 14 int n = sizeof(a) / sizeof(a[0]); 15 16 for (i = 0; i < n; i++) 17 { 18 //printf("%d, ", a[i]); 19 printf("%d, ", *(a+i)); 20 } 21 printf("\n"); 22 23 int *p = a; //定义一个指针变量保存a的地址 24 for (i = 0; i < n; i++) 25 { 26 p[i] = 2 * i; 27 } 28 29 for (i = 0; i < n; i++) 30 { 31 printf("%d, ", *(p + i)); 32 } 33 printf("\n"); 34 35 36 return 0; 37 }
2、指针加减运算
(1)加法运算
指针计算可不是简单的整数相加,如果是一个int *,+1的结果是增加一个int的大小,如果是一个char *,+1的结果是增加一个char大小
1 #include <stdio.h> 2 3 int main() 4 { 5 int a; 6 int *p = &a; 7 printf("%d\n", p); 8 p += 2;//移动了2个int 9 printf("%d\n", p); 10 11 char b = 0; 12 char *p1 = &b; 13 printf("%d\n", p1); 14 p1 += 2;//移动了2个char 15 printf("%d\n", p1); 16 17 return 0; 18 }
(2)减法运算
和加法同理
1 #include <stdio.h> 2 3 int main() 4 { 5 int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 6 int i = 0; 7 int n = sizeof(a) / sizeof(a[0]); 8 9 int *p = a+n-1; 10 for (i = 0; i < n; i++) 11 { 12 printf("%d, ", *p); 13 p--; 14 } 15 16 return 0; 17 }
1 #include <stdio.h> 2 3 int main() 4 { 5 int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 6 int *p2 = &a[2]; //第2个元素地址 7 int *p1 = &a[1]; //第1个元素地址 8 printf("p1 = %p, p2 = %p\n", p1, p2); 9 10 int n1 = p2 - p1; //n1 = 1,因为是两个int *型的指针相减,所以得到的是1 11 int n2 = (int)p2 - (int)p1; //n2 = 4,两个in类型的数相减,所以是4 12 printf("n1 = %d, n2 = %d\n", n1, n2); 13 14 return 0; 15 }
3、指针数组
指针数组,它是数组,数组的每个元素都是指针类型。每个元素存储的都是字符串(内存地址)。
1 #include <stdio.h> 2 3 int main() 4 { 5 //指针数组 6 int *p[3]; 7 int a = 1; 8 int b = 2; 9 int c = 3; 10 int i = 0; 11 12 p[0] = &a; 13 p[1] = &b; 14 p[2] = &c; 15 16 for (i = 0; i < sizeof(p) / sizeof(p[0]); i++ ) 17 { 18 printf("%d, ", *(p[i])); 19 } 20 printf("\n"); 21 22 return 0; 23 }
4、数组指针(行指针)
数组指针,指向数组的指针。
1 /* 2 指向一维数组的指针变量,定义方法:*指针变量名 3 4 */ 5 #include <stdio.h> 6 7 int main() 8 { 9 int i; 10 int a[5]; 11 int *p=a; 12 13 for (i = 0; i < 5; i++) 14 { 15 *p = i; 16 p++; 17 18 } 19 20 /* 21 注意如果没有这句话就不能正确输出数组元素 22 因为p指针指向的地址在数值上等于a[4]的地址+4 23 这句话相当于让p重新指向a 24 */ 25 p = a; 26 for (i = 0; i < 5; i++) 27 { 28 printf("a[%d]=%d\n", i, *p); 29 p++; 30 } 31 return 0; 32 }
1 #include <stdio.h> 2 3 int main() 4 { 5 6 int a[3][4] = { 1,9,6,7,8,6,13,0,9,10,11,12 }; 7 //数组指针 8 /* 9 指向二维数组的指针变量,定义方法:(*指针变量名)[长度] 10 “长度”表示二维数组分解为多个一维数组时,一维数组的长度,也就是二维数组的列数。 11 */ 12 13 int(*p)[4];//首先说明p是一个指针,指向一个整型的一维数组,这个一维数组的长度是4,也可以说是p的步长。也就是说执行p+1时,p要跨过4个整型数据的长度。 14 int i = 0, j = 0; 15 p = a; 16 for (i = 0; i < 3; i++) 17 { 18 for (j = 0; j < 4; j++) printf("%d,", p[i][j]); //或者 *(*(p+i)+j) 或者 *(p[i]+j) 19 printf("\n"); 20 } 21 22 23 /* 24 在有些时候数组指针和指针数组是相似的 25 下面是利用指针数组也可完成以上操作 26 */ 27 int x = 0; 28 int *p1[3]; 29 /* 30 明确一点:如果有整型二维数组a[3][4],a[0],a[1],a[2]表示的都是对应那行的数组首地址,和数组名,而不是一个元素 31 注意:p1[3]={p1[0],p1[1],p1[2]}; 32 我们让p1[0]指向a[0],p1[1]->a[1],p1[2]->a[2], 33 p1[0]存的是a[0]的地址,p1[1]存的是a[1],p1[2]存的是a[2] 34 也就是存的是二维数组a的每一行的首地址 35 明确一点:p1指的是:数组p1中的首元素地址,*p1指的是:取出首元素存储的内容 36 也就是p1[0]==*p1 37 */ 38 for (x=0; x < 3; x++) 39 { 40 p1[x] = a[x]; 41 } 42 /* 43 执行完上面那个循环之后, 44 p1[0]和p1[1]的指针地址差4个int型大小字节,p[1]和p1[2]也是差4个int型大小的字节,也就是16个字节 45 那么:*p1[0]==a[0][0],*(p1[0]+1)==a[0][1],*(p1[0]+2)==a[0][2],*(p1[0]+3)==a[0][3] 46 *p1[1]==a[1][0],*(p1[1]+1)==a[1][1],*(p1[1]+2)==a[1][2],*(p1[2]+3)==a[1][3] 47 以此类推。。。。。。 48 */ 49 printf("\n"); 50 for (i=0; i < 3; i++) 51 { 52 for (j = 0; j < 4; j++) 53 { 54 printf("%d,", *(*(p1 + i) + j));//或者 p1[i][j] 或者 *(p1[i]+j) 55 56 } 57 printf("\n"); 58 } 59 60 return 0; 61 }
5、多级指针
C语言允许有多级指针存在,在实际的程序中一级指针最常用,其次是二级指针。
二级指针就是指向一个一级指针变量地址的指针。
三级指针基本用不着,但有些考试会考。
1 #include <stdio.h> 2 3 int main() 4 { 5 int a = 10; 6 int *p = &a; //一级指针 7 *p = 100; //*p就是a 8 9 int **q = &p; 10 //*q就是p 11 //**q就是a 12 13 int ***t = &q; 14 //*t就是q 15 //**t就是p 16 //***t就是a 17 18 return 0; 19 }
三、指针和函数
1、函数形参改变实参的值
1 #include <stdio.h> 2 3 void swap1(int x, int y) 4 { 5 int tmp; 6 tmp = x; 7 x = y; 8 y = tmp; 9 printf("x = %d, y = %d\n", x, y); 10 } 11 12 void swap2(int *x, int *y) 13 { 14 int tmp; 15 tmp = *x; 16 *x = *y; 17 *y = tmp; 18 } 19 20 int main() 21 { 22 int a = 3; 23 int b = 5; 24 swap1(a, b); //值传递 25 printf("a = %d, b = %d\n", a, b); 26 27 a = 3; 28 b = 5; 29 swap2(&a, &b); //地址传递 30 printf("a2 = %d, b2 = %d\n", a, b); 31 32 return 0; 33 }
2、数组名做函数参数
1 #include <stdio.h> 2 3 void printArrary(int *a, int n) 4 { 5 int i = 0; 6 for (i = 0; i < n; i++) 7 { 8 printf("%d, ", a[i]); 9 } 10 printf("\n"); 11 } 12 13 int main() 14 { 15 int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 16 int n = sizeof(a) / sizeof(a[0]); 17 18 //数组名做函数参数 19 printArrary(a, n); 20 return 0; 21 }
3、指针做为函数的返回值(指针函数)
1 #include <stdio.h> 2 3 int a = 10; 4 5 int *getA() 6 { 7 return &a; 8 } 9 10 11 int main() 12 { 13 *( getA() ) = 111; 14 printf("a = %d\n", a); 15 16 return 0; 17 }
4、函数指针
函数指针是指向函数的指针变量。函数指针有两个用途:调用函数和做函数的参数。
1 /* 2 一、第一种(可能在某种编译器上不能使用) 3 函数指针的声明方法为: 4 返回值类型 (*指针变量名) ([形参列表]); 5 注1:“返回值类型”说明函数的返回类型,“(指针变量名)”中的括号不能省,括号改变了运算符的优先级。 6 若省略整体则成为一个函数说明,说明了一个返回的数据类型是指针的函数,后面的“形参列表”表示指针变量指向的函数所带的参数列表。 7 例如: 8 int func(int x); 声明一个函数 9 int (*f) (int x); 声明一个函数指针 10 f = func; 将func函数的首地址赋给指针f 11 或者使用下面的方法将函数地址赋给函数指针: 12 f = &func; 13 赋值时函数func不带括号,也不带参数,由于func代表函数的首地址,因此经过赋值以后,指针f就指向函数func(x)的代码的首地址。 14 注2:函数括号中的形参可有可无,视情况而定。 15 16 二、第二种 17 1.定义函数指针类型: 18 typedef int (*fun)(int,int); 19 2.声明变量,赋值: 20 fun func=max; 21 也就是说,赋给函数指针的函数应该和函数指针所指的函数原型是一致的。 22 */ 23 #include <stdio.h> 24 25 int max(int x,int y) 26 { 27 return (x > y ? x : y); 28 } 29 int main() 30 { 31 int a = 1; 32 int b = 2; 33 //第一种 34 int(*ptrc)(int, int); 35 ptrc = max; 36 printf("max=%d\n", ptrc(a, b)); 37 38 //第二种 39 typedef int(*ptr)(int, int); 40 ptr ptr1 = max; 41 printf("max=%d\n", ptr1(a, b)); 42 43 return 0; 44 }
四、指针和字符串
1、字符指针
1 #include <stdio.h> 2 3 int main() 4 { 5 char string[] = "hello world"; 6 char *p = string; 7 *p = 'H'; 8 p++; 9 *p = 'E'; 10 printf("%s\n", string); 11 12 p = "我来康康"; 13 printf("%s\n", p); 14 15 char *p1 = "我来康康,我来康康"; 16 printf("%s\n", p1); 17 18 return 0; 19 }
2、字符指针做函数参数
1 #include <stdio.h> 2 /*mystrcat(char *dest, const char *src) 3 功能:将字符串src追加到字符串dest中 4 */ 5 6 void mystrcat(char *dest, const char *src) 7 { 8 int len1 = 0; 9 int len2 = 0; 10 while (dest[len1]) 11 { 12 len1++; 13 } 14 while (src[len2]) 15 { 16 len2++; 17 } 18 19 int i; 20 for (i = 0; i < len2; i++) 21 { 22 dest[len1 + i] = src[i]; 23 } 24 } 25 26 int main() 27 { 28 char dst[100] = "hello,"; 29 char src[] = "我是我来康康"; 30 31 mystrcat(dst, src); 32 printf("dst = %s\n", dst); 33 34 return 0; 35 }
3、 const修饰的指针变量
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 int main(void) 6 { 7 //const修饰一个变量为只读,不可修改 8 const int a = 10; 9 10 //指针变量指向的内存地址, 指针指向的内存所存内容, 2个不同概念 11 char buf[] = "agearhjdgkyulyu"; 12 13 //从左往右看,跳过类型,看修饰哪个字符 14 //如果是*, 说明指针指向的内存所存内容不能改变 15 //如果是指针变量,说明指针的指向的内存地址不能改变,即指针变量的值不能修改 16 const char *p = buf; 17 // 等价于上面 char const *p1 = buf; 18 //p[1] = '2'; //err 19 p = "agdlsjaglkdsajgl"; //ok 20 21 char * const p2 = buf; 22 p2[1] = '3'; 23 //p2 = "salkjgldsjaglk"; //err 24 25 //p3为只读,指向不能变,指向的内存也不能变 26 const char * const p3 = buf; 27 28 return 0; 29 }
4、指针数组做为main函数的形参
1 /* 2 int main(int argc, char *argv[]); 3 main函数是操作系统调用的,第一个参数标明argc数组的成员数量,argv数组的每个成员都是char *类型 4 argv是命令行参数的字符串数组 5 argc代表命令行参数的数量,程序名字本身算一个参数 6 ------------------------------------------------------------------ 7 Linux下在执行gcc -o xxx.c xxx之后,也就是生成二进制文件之后 8 执行./xxx argv[1] arfv[2]...(注意:argv[0]是./xxx) 9 例如:./hello a b 10 ------------------------------------------------------------------ 11 在vs中:调制-》你工程名属性(应该在最后一行)-》调试-》命令参数(注意以空格为分隔符) 12 vc我没用过,不知道,可自行百度 13 */ 14 #include <stdio.h> 15 16 //argc: 传参数的个数(包含可执行程序) 17 //argv:指针数组,指向输入的参数 18 int main(int argc, char *argv[]) 19 { 20 21 //指针数组,它是数组,每个元素都是指针 22 char *a[] = { "aaaaaaa", "bbbbbbbbbb", "ccccccc" }; 23 int i = 0; 24 25 printf("argc = %d\n", argc); 26 for (i = 0; i < argc; i++) 27 { 28 printf("%s\n", argv[i]); 29 } 30 return 0; 31 }
5、项目开发常用字符串应用模型
(1)strstr中的while和do-while模型
C 库函数 char *strstr(const char *haystack, const char *needle)
在字符串 haystack 中查找第一次出现字符串 needle 的位置,不包含终止符 '\0'。
利用strstr标准库函数找出一个字符串中substr出现的个数
·i while模型
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 int main(void) 6 { 7 char *p = "11abcdabcabcddabcabcd1232abcdabcbcdcbdaqqq"; 8 int n = 0; 9 10 while ((p = strstr(p, "abcd")) != NULL)//p = strstr(p, "abcd")--将p指向abcd的位置 11 { 12 //能进来,肯定有匹配的子串 13 //重新设置起点位置 14 //C 库函数 size_t strlen(const char *str) 计算字符串 str 的长度,直到空结束字符,但不包括空结束字符。 15 p = p + strlen("abcd");//将p指向abcd后面的位置 16 n++; 17 18 if (*p == 0) //如果到结束符 19 { 20 break; 21 } 22 23 } 24 25 printf("n = %d\n", n); 26 27 return 0; 28 }
·ii do-while模型
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 int main(void) 6 { 7 char *p = "11abcd111122abcd333abcd3322abcd3333322qqq"; 8 int n = 0; 9 10 do 11 { 12 p = strstr(p, "abcd"); 13 if (p != NULL) 14 { 15 n++; //累计个数 16 17 //重新设置查找的起点 18 p = p + strlen("abcd"); 19 20 } 21 else //如果没有匹配的字符串,跳出循环 22 { 23 break; 24 } 25 } while (*p != 0); //如果没有到结尾 26 27 printf("n = %d\n", n); 28 return 0; 29 }
(2)字符串反转模型(逆置)
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 int inverse(char *p) 6 { 7 if (p == NULL) 8 { 9 return -1; 10 } 11 char *str = p; 12 int begin = 0; 13 int end = strlen(str) - 1; 14 char tmp; 15 16 while (begin < end) 17 { 18 //交换元素 19 tmp = str[begin]; 20 str[begin] = str[end]; 21 str[end] = tmp; 22 23 begin++; //往右移动位置 24 end--; //往左移动位置 25 } 26 27 return 0; 28 } 29 30 int main(void) 31 { 32 //char *str = "abcdefg"; //文件常量区,内容不允许修改 33 char str[] = "abcdef"; 34 35 int ret = inverse(str); 36 if (ret != 0) 37 { 38 return ret; 39 } 40 41 printf("str:%s\n", str); 42 return 0; 43 }
补充:字符串处理函数
/*
#include <string.h>
char *strcpy(char *dest, const char *src);
功能:把src所指向的字符串复制到dest所指向的空间中,'\0'也会拷贝过去
参数:
dest:目的字符串首地址
src:源字符首地址
返回值:
成功:返回dest字符串的首地址
失败:NULL
注意:如果参数dest所指的内存空间不够大,可能会造成缓冲溢出的错误情况。
----------------------------------------------------------------------------------------------------------
strncpy()
#include <string.h>
char *strncpy(char *dest, const char *src, size_t n);
功能:把src指向字符串的前n个字符复制到dest所指向的空间中,是否拷贝结束符看指定的长度是否包含'\0'。
参数:
dest:目的字符串首地址
src:源字符首地址
n:指定需要拷贝字符串个数
返回值:
成功:返回dest字符串的首地址
失败:NULL
----------------------------------------------------------------------------------------------------------
#include <string.h>
char *strcat(char *dest, const char *src);
功能:将src字符串连接到dest的尾部,‘\0’也会追加过去
参数:
dest:目的字符串首地址
src:源字符首地址
返回值:
成功:返回dest字符串的首地址
失败:NULL
----------------------------------------------------------------------------------------------------------
#include <string.h>
char *strncat(char *dest, const char *src, size_t n);
功能:将src字符串前n个字符连接到dest的尾部,‘\0’也会追加过去
参数:
dest:目的字符串首地址
src:源字符首地址
n:指定需要追加字符串个数
返回值:
成功:返回dest字符串的首地址
失败:NULL
----------------------------------------------------------------------------------------------------------
#include <string.h>
int strcmp(const char *s1, const char *s2);
功能:比较 s1 和 s2 的大小,比较的是字符ASCII码大小。
参数:
s1:字符串1首地址
s2:字符串2首地址
返回值:
相等:0
大于:>0 在不同操作系统strcmp结果会不同 返回ASCII差值
小于:<0
----------------------------------------------------------------------------------------------------------
#include <string.h>
int strncmp(const char *s1, const char *s2, size_t n);
功能:比较 s1 和 s2 前n个字符的大小,比较的是字符ASCII码大小。
参数:
s1:字符串1首地址
s2:字符串2首地址
n:指定比较字符串的数量
返回值:
相等:0
大于: > 0
小于: < 0
----------------------------------------------------------------------------------------------------------
#include <stdio.h>
int sprintf(char *str, const char *format, ...);
功能:根据参数format字符串来转换并格式化数据,然后将结果输出到str指定的空间中,直到出现字符串结束符 '\0' 为止。
参数:
str:字符串首地址
format:字符串格式,用法和printf()一样
返回值:
成功:实际格式化的字符个数
失败: - 1
----------------------------------------------------------------------------------------------------------
#include <stdio.h>
int sscanf(const char *str, const char *format, ...);
功能:从str指定的字符串读取数据,并根据参数format字符串来转换并格式化数据。
参数:
str:指定的字符串首地址
format:字符串格式,用法和scanf()一样
返回值:
成功:参数数目,成功转换的值的个数
失败: - 1
----------------------------------------------------------------------------------------------------------
#include <string.h>
char *strchr(const char *s, int c);
功能:在字符串s中查找字母c出现的位置
参数:
s:字符串首地址
c:匹配字母(字符)
返回值:
成功:返回第一次出现的c地址
失败:NULL
----------------------------------------------------------------------------------------------------------
#include <string.h>
char *strstr(const char *haystack, const char *needle);
功能:在字符串haystack中查找字符串needle出现的位置
参数:
haystack:源字符串首地址
needle:匹配字符串首地址
返回值:
成功:返回第一次出现的needle地址
失败:NULL
----------------------------------------------------------------------------------------------------------
#include <string.h>
char *strtok(char *str, const char *delim);
功能:来将字符串分割成一个个片段。当strtok()在参数s的字符串中发现参数delim中包含的分割字符时, 则会将该字符改为\0 字符,当连续出现多个时只替换第一个为\0。
参数:
str:指向欲分割的字符串
delim:为分割字符串中包含的所有字符
返回值:
成功:分割后字符串首地址
失败:NULL
在第一次调用时:strtok()必需给予参数s字符串
往后的调用则将参数s设置成NULL,每次调用成功则返回指向被分割出片段的指针
----------------------------------------------------------------------------------------------------------
#include <stdlib.h>
int atoi(const char *nptr);
功能:atoi()会扫描nptr字符串,跳过前面的空格字符,直到遇到数字或正负号才开始做转换,而遇到非数字或字符串结束符('\0')才结束转换,并将结果返回返回值。
参数:
nptr:待转换的字符串
返回值:成功转换后整数
类似的函数有:
atof():把一个小数形式的字符串转化为一个浮点数。
atol():将一个字符串转化为long类型
*/
浙公网安备 33010602011771号