指针进阶 字符指针
字符指针的另一种使用方式
#include int main(){ //字符指针的使用 char ch = 'q'; char * pc = &ch; //本质上是把这个字符串的首字符地址存储在了指针变量ps中 const char * ps = "hello world"; //数组存储字符串时,是把整个字符串都存储在其中。 char arr[] = "hello world"; printf("%cn",*ps);//h printf("%sn",ps);//hello world %s打印,遇到字符串结束符停止 printf("%sn",arr);//hello world return 0;}
因为常量字符串不可以被修改,所以相同的常量字符串,在内存中只会存储一份。
#include int main(){ //每个数组初始化都会开辟空间,即使两个数组中保存的是相同的数据,也会另外开辟空间,其内存地址不同。 char str1[] = "hello world."; char str2[] = "hello world.";// char * str3 = "hello world.";// char * str4 = "hello world."; //这里的"hello world."是一个常量字符串。不能使用*解引用操作修改。 //因为不能使用*修改,所以一般要使用const修饰,是用于修饰*str3或*str4,所以const要写在*的左边 const char * str3 = "hello world."; const char * str4 = "hello world."; /int main(){ //整型指针,指向整型的指针; int i = 10; int *pi = &i; // 字符指针,是指向字符的指针。 char c = 'c'; char * pc = &c; //数组指针 int arr[10] = {0}; //数组名是数组首元素的地址,arr存储数组首元素地址;&arr,取出的是整个数组的地址。 //因为[]下标引用符的优先级比*解引用操作符的优先级高,所以这样写就成了指针数组: //int * parr[10] = &arr; //所以要先让*与parr结合,这样就是指针了,结合之后再与[10]结合,就叫做数组指针 //parr就是一个数组指针,其中存放的是一个数组的地址。int表示指向的数组是int类型的,[10]表示指向的数组中存储了10个元素 int (*parr)[10] = &arr; //d是一个指针数组,其中存储的是一级浮点型指针 double * d[5]; //取d的地址,是取出d这个数组。d这个数组是double*类型的 ,有5个元素。 //又因为是存储数组的地址,所以pd是一个数组指针。加()先与*结合,再与[]结合 double* (*pd)[5] = &d; return 0;}
数组名 与 &数组名 的区别
#include int main(){ int arr[9] = {0}; //arr和&arr分别是什么? int * p1 = arr; int (*p2)[9] = &arr; //数组名arr表示的是数组首元素的地址,arr+1,加了4个字节,也就是加一个int类型大小。 printf("%pn",p1);//0000009cbf1ff780 printf("%pn",p1+1);//0000009cbf1ff784 //&arr,取出的是整个数组,&arr+1,加的是0x24,十进制就是36个字节,加的是整个数组大小。 printf("%pn",p2);//0000009cbf1ff780 printf("%pn",p2+1);//0000009cbf1ff7a4 return 0;}
数组指针使用示例,并不建议这样使用。
#include int main(){ int arr[10] = {0,1,2,3,4,5,6,7,8,9}; int (*pa)[10] = &arr; int i; for(i=0 ; i<10 ; i++) { /
函数指针
函数指针语法
//函数返回类型 (*函数指针变量名)(函数参数[,函数参数......]) = 函数名/&函数名#include int Add(int x,int y){ return x+y;}void test(char* str){}int main(){ //函数指针——存放函数地址的指针。 //&函数名:取出函数的地址。 printf("%pn",&Add);//00007ff6562617a1 //函数名,表示的也是函数的地址。 函数名==&函数名 printf("%pn",Add);//00007ff6562617a1 //pf就是一个函数指针变量。 //因为()优先级要比*高,所以要写成(*pf),意思是pf是一个指针,指向参数为(int,int),返回类型为int的函数。 //int (*pf)(int,int) = &Add; //printf("%pn",*pf);//00007ff6562617a1 //test函数指针 void (*pt)(char*) = &test; //通过指针调用函数: //先解引用(*pf)找到这个函数然后传递参数(3,5)。然后使用变量接收返回值。 //int ret = (*pf)(3,5); //printf("%d",ret);//8 //因为&函数名与函数名等效。也就是说Add的地址直接放到了pf中 //函数Add保存的是函数本身的地址,pf保存的是Add函数的地址。所以Add === pf int (*pf)(int,int) = Add; //平时我们调用函数: int ret = Add(3,9); printf("%dn",ret);//12 //使用指针解引用调用 ret = (*pf)(10,33); printf("%dn",ret);//43 //因为Add===pf,所以我们也可以这样调用: ret = pf(22,44); printf("%dn",ret);//66 //所以调用时,(*pf)===pf===Add return 0;}
《C陷阱和缺陷》中的两段代码解读
int main(){ //使用typedef对类型进行重定义 //typedef void(*)(int) pfun_t; 指针类型的*要与名字写在一起,所以就成为: typedef void(*pfun_t)(int); //将void(*)(int)函数指针类型,重命名为pfun_t pfun_t signal(int,pfun_t); return 0;}
函数指针数组
函数指针数组的定义
//函数指针数组:存放函数指针的数组//函数指针数组定义语法:指向的函数的返回类型 (*函数指针数组变量名[函数指针数组元素个数])(函数参数);int Add(int x, int y){ return x+y;}int Sub(int x, int y){ return x-y;}int main(){ int (*pf1)(int,int) = Add; int (*pf2)(int,int) = Sub; //函数指针数组,也是一个数组,所以直接在变量名后面加[2]。*pfArr[2]就表示一个指针数组 //剩下的int (int,int)是数组元素类型。也就是说每个元素都指向一个参数为(int,int),返回类型为int的函数。 int(*pfArr[2])(int,int) = {Add, Sub}; return 0;}
函数指针数组的应用:计算器
//计算器,计算整型变量的加减乘除。#include int Add(int x , int y){ return x+y;}int Sub(int x , int y){ return x-y;}int Mul(int x , int y){ return x*y;}int Div(int x , int y){ return x/y;}void menu(){ printf("------------------------------------n"); printf("------输入菜单序号执行对应功能---------n"); printf("------------- 0.退出 ----------------n"); printf("------------- 1.加法 ----------------n"); printf("------------- 2.减法 ----------------n"); printf("------------- 3.乘法 ----------------n"); printf("------------- 4.除法 ----------------n"); printf("-------------------------------------n");}int main(){ //条件 int input = 1; //函数指针数组 int(*pfArr[5])(int,int) = {0,Add,Sub,Mul,Div}; //循环 while(input) { menu(); printf("请选择:"); scanf("%d",&input); if(input >0 && input<5) { int x,y,ret; printf("输入要进行操作的两个数:"); scanf("%d %d",&x,&y); //ret = (*pfArr[input])(x,y); ///一个数组,如 int arr[10]//去掉数组名,是数组类型:int [10] ; 去掉数组名[],是数组中的元素类型:int#include void test(const char* str){ printf("%sn",str);}int main(){ //函数指针pfun void (*pfun)(const char*) = test; //函数指针数组pfunArr void (* pfunArr[5])(const char*); pfunArr[0] = test; //指向函数指针数组pfunArr的指针ppfunArr void (*(*ppfunArr)[5])(const char *) = &pfunArr; return 0;}
回调函数
回调函数是什么?
使用回调函数改进以下程序
#include int Add(int a, int b){ return a + b;}int Sub(int a, int b){ return a - b;}int Mul(int a, int b){ return a*b;}int Div(int a, int b){ return a / b;}void menu(){ printf("------------------------------------n"); printf("------输入菜单序号执行对应功能---------n"); printf("------------- 0.退出 ----------------n"); printf("------------- 1.加法 ----------------n"); printf("------------- 2.减法 ----------------n"); printf("------------- 3.乘法 ----------------n"); printf("------------- 4.除法 ----------------n"); printf("-------------------------------------n");}int main(){ int x, y; int input = 1; int ret = 0; do { menu(); printf( "请选择:" ); scanf( "%d", &input); switch (input) { case 1: printf( "输入操作数:" ); scanf( "%d %d", &x, &y); ret = Add(x, y); printf( "ret = %dn", ret); break; case 2: printf( "输入操作数:" ); scanf( "%d %d", &x, &y); ret = Sub(x, y); printf( "ret = %dn", ret); break; case 3: printf( "输入操作数:" ); scanf( "%d %d", &x, &y); ret = Mul(x, y); printf( "ret = %dn", ret); break; case 4: printf( "输入操作数:" ); scanf( "%d %d", &x, &y); ret = Div(x, y); printf( "ret = %dn", ret); break; case 0: printf("退出程序n"); break; default: printf( "选择错误n" ); break; } } while (input); return 0;}
改进
#include int Add(int a, int b){ return a + b;}int Sub(int a, int b){ return a - b;}int Mul(int a, int b){ return a*b;}int Div(int a, int b){ return a / b;}void menu(){ printf("------------------------------------n"); printf("------输入菜单序号执行对应功能---------n"); printf("------------- 0.退出 ----------------n"); printf("------------- 1.加法 ----------------n"); printf("------------- 2.减法 ----------------n"); printf("------------- 3.乘法 ----------------n"); printf("------------- 4.除法 ----------------n"); printf("-------------------------------------n");}void calc(int (*pf)(int,int )){ int x, y,ret; printf( "输入操作数:" ); scanf( "%d %d", &x, &y); ret = pf(x, y); printf( "ret = %dn", ret);}int main(){ int input = 1; do { menu(); printf( "请选择:" ); scanf( "%d", &input); switch (input) { case 1: calc(Add); break; case 2: calc(Sub); break; case 3: calc(Mul); break; case 4: calc(Div); break; case 0: printf("退出程序n"); break; default: printf( "选择错误n" ); break; } } while (input); return 0;}
复习:冒泡排序的实现
#include void bubble_sort(int arr[], int sz){ int i,j; //冒泡排序的趟数:有10个元素,就要排序9趟,剩下最后一个元素不用再于别的元素比较。趟数=元素个数-1 for(i=0 ; i arr[j+1]) { int tmp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = tmp; } } }}int main(){ //升序 int arr[10] = {9,8,7,6,5,4,3,2,1,0}; int sz = sizeof(arr)/sizeof(arr[0]); bubble_sort(arr,sz); int i; for(i=0 ; i
qsort排序函数的使用
#include #include #include void print(int arr[],int sz){ int i; for(i=0 ; ip2;如果小于,返回的是一个小于0的数,就表示p1name,(s+i)->age); }}int cmp_age(const void* p1,const void* p2){ return ((struct Stu*)p1)->age - ((struct Stu*)p2)->age;}int cmp_name(const void* p1,const void* p2){ return strcmp(((struct Stu*)p1)->name,((struct Stu*)p2)->name);}void qsort_stu(){ //使用qsort函数为结构体数据排序 struct Stu s[] = {{"zhangsan",30},{"lisi",34},{"wangwu",20}}; int sz = sizeof(s)/sizeof(s[0]); printf("排序前:n"); print_stu(s,sz); //按照年龄排序 //qsort(s,sz, sizeof(s[0]),cmp_age); //按照名字排序 qsort(s,sz,sizeof(s[0]),cmp_name); printf("排序后:n"); print_stu(s,sz);}int main(){ //整型数据的排序 //qsort_int(); //结构体数据的排序 qsort_stu();}
模拟qsort实现一个冒泡排序算法
#include #include Swap(char* buf1,char* buf2,int size){ int i; for(i=0 ; i0) { //交换 //交换的是两个指针指向的内容。但是我们只是知道地址,而不知道其是什么类型的数据。 //解决:不管其是什么类型的数据,我们把他们的每个字节的内容都进行交换,这样也相当于交换了内容。 Swap((char*)base+j*size,(char*)base+(j+1)*size,size); } } }}int cmp_int(const void* p1,const void* p2){ //因为p1与p2都是void* 无类型指针。没有办法比较。 //而我们知道传入的数据是int类型的,所以我们可以将其先强制类型转换为int*类型的指针(int*)p1、(int*)p2 //然后再解引用,就可以进行比较了。*(int*)p1 - *(int*)p2 //如果p1大于p2,就会将这个值返回,返回的是一个大于0的数,就表示p1>p2;如果小于,返回的是一个小于0的数,就表示p1name,(s+i)->age); }}int cmp_age(const void* p1,const void* p2){ return ((struct Stu*)p1)->age - ((struct Stu*)p2)->age;}int cmp_name(const void* p1,const void* p2){ return strcmp(((struct Stu*)p1)->name,((struct Stu*)p2)->name);}void qsort_stu(){ //使用qsort函数为结构体数据排序 struct Stu s[] = {{"zhangsan",30},{"lisi",34},{"wangwu",20}}; int sz = sizeof(s)/sizeof(s[0]); printf("排序前:n"); print_stu(s,sz); //按照年龄排序 //bubble_sort(s,sz, sizeof(s[0]),cmp_age); //按照名字排序 bubble_sort(s,sz,sizeof(s[0]),cmp_name); printf("排序后:n"); print_stu(s,sz);}int main(){ //test(); qsort_stu(); return 0;}
void *类型
#include int main(){ int a = 10; char ch = 'w'; //void为无具体类型,void*就是无具体类型指针。其指针变量中,什么类型的变量地址都可以存储。 void* p = &a; p = &ch; //但是在引用的时候不能直接引用,因为void*是无具体类型的,所以解引用或进行指针运算,编译器不知道访问几个字节。 /#include int main(){ int a[] = {1,2,3,4}; //sizeof(数组名),计算整个数组的大小。int类型数组中有4个元素。4*4=16 printf("%dn",sizeof(a));//16 //a+0,a中存储数组首元素地址,首元素地址+0:代表的还是首元素地址。sizeof(a+0)计算地址的大小 //在32位平台下,地址大小是4个字节;在64位平台下,地址是8个字节。 printf("%dn",sizeof(a+0));//8 //数组名a中存储的是数组首元素的地址,解引用找到的是数组首元素:1。1是int类型数据,所以应该是4 printf("%dn",sizeof(*a));//4 //a+1,a中存储数组首元素地址,首元素地址+1:代表的数组中第二个元素的地址。sizeof(a+1)计算地址的大小 printf("%dn",sizeof(a+1));//4/8 //计算数组中第二个元素的大小。 printf("%dn",sizeof(a[1])); //&a,取出整个数组地址。sizeof(地址) 4/8 printf("%dn",sizeof(&a));//8 //&a,取出整个数组地址。解引用找到数组。也就是计算整个数组大小 printf("%dn",sizeof(*&a));//16 //&a,取出整个数组地址。数组地址+1,跳过整个数组之后的一块地址。还是一个地址,所以这里是计算地址的大小。4/8 printf("%dn",sizeof(&a+1));//8 //a[0]是数组首元素,&a[0]取出数组首元素地址。是一个地址,4/8 printf("%dn",sizeof(&a[0]));//8 //a[0]是数组首元素,&a[0]取出数组首元素地址,&a[0]+1,数组首元素地址+1,就是数组第二个元素地址。是一个地址,4/8 printf("%dn",sizeof(&a[0]+1));//8 return 0;}
字符数组(不存放字符串结束符),sizeof以及strlen的计算
#include #include int main(){ char arr[] = {'a','b','c','d','e','f'}; //计算字符串长度,strlen计算字符串长度时,直到遇见字符串结束符''才结束 //arr是首元素地址,会一直往后取。直到碰到才结束。所以这里是个随机值 printf("n%dn",strlen(arr));//随机值 //首元素地址+0,还是首元素地址。然后往后取,直到碰到才结束。与以上相同,是个随机值。 printf("%dn",strlen(arr+0));//随机值 //strlen函数的原型:size_t __cdecl strlen(const char *_Str); //其参数是一个指针,也就是说参数应该是一个指针,或者直接传地址过去。 //&arr,取出的是整个数组地址,该地址是int (*)[6]类型。然后放入strlen函数,被强制类型转换为char*类型。 //也会从数组首元素开始取,直到碰到字符串结束符结束 printf("%dn",strlen(&arr));//随机值 //&arr+1,紧接着数组地址后的一块地址。该地址也是int (*)[6]类型。然后放入strlen函数,被强制类型转换为char*类型。 //会从数组后第一个元素开始取,直到碰到字符串结束符结束。也就是说要比以上随机值少6个字符。 printf("%dn",strlen(&arr+1));//随机值-6 //arr[0]是数组首元素,&arr[0]取出数组首元素地址,&arr[0]+1,数组首元素地址+1,就是数组第二个元素地址。 //从数组第二个元素取直到取到字符串结束符,少了数组首元素。所以应该是随机值-1 printf("%dn",strlen(&arr[0]+1));//随机值-1 / //注意:字符串长度,不计算最后的字符串结束符 //计算字符串长度,strlen计算字符串长度时,直到遇见字符串结束符''才结束 //arr是首元素地址,会一直往后取。直到碰到才结束。这里是6 printf("n%dn",strlen(arr));//6 //首元素地址+0,还是首元素地址。然后往后取,直到碰到才结束。与以上相同,是6 printf("%dn",strlen(arr+0));//6 //strlen函数的原型:size_t __cdecl strlen(const char *_Str); //其参数是一个指针,也就是说参数应该是一个指针,或者直接传地址过去。 //&arr,取出的是整个数组地址,该地址是int (*)[6]类型。然后放入strlen函数,被强制类型转换为char*类型。 //也会从数组首元素开始取,直到碰到字符串结束符结束 printf("%dn",strlen(&arr));//6 //&arr+1,紧接着数组地址后的一块地址。该地址也是int (*)[6]类型。然后放入strlen函数,被强制类型转换为char*类型。 //会从数组后第一个元素开始取,直到碰到字符串结束符结束。也就是说是个随机值 printf("%dn",strlen(&arr+1));//随机值 //arr[0]是数组首元素,&arr[0]取出数组首元素地址,&arr[0]+1,数组首元素地址+1,就是数组第二个元素地址。 //从数组第二个元素取直到取到字符串结束符,少了数组首元素。所以应该是6-1=5 printf("%dn",strlen(&arr[0]+1));//5 / //strlen函数的原型:size_t __cdecl strlen(const char *_Str); // 其参数是一个指针,也就是说参数应该是一个指针,或者直接传地址过去。 //p是一个指针,指向a。一直取到字符串结束,是6 printf("%dn",strlen(p));//6 //p是指向a的char类型指针,p+1,跳过1个字节,就是指向b。从b开始取到字符串结束,6-1=5 printf("%dn",strlen(p+1));//5 //&p,取出的是p的地址。&p是一个char**类型,放入strlen函数,被强制转换为char*类型。 //&p是一个地址,占8个字节。每个字节都被当作一个字符。直到取到(或者是十六进制的00)才会结束,其后面不知道什么时候才能取到字符串结束符,所以这里是一个随机值。 printf("&p:%dn",strlen(&p));//随机值 //&p,取出的是p的地址。&p+1,是&p后面紧接着的那个地址。其后面不知道什么时候才能取到字符串结束符,所以这里是一个随机值 printf("&p+1:%dn",strlen(&p+1));//随机值 //这两个地址都是随机值,有没有什么联系呢? //可能有联系、可能没有联系 //没有联系的情况: //p变量的地址(&p):0x00 00 7f f7 60 31 a0 10 //因为内存中采用小端存储形式,也就是低位低地址。所以&p存储到内存中是:10 a0 31 60 f7 7f 00 00。 //本来使用指针来取,则是倒着取出来。但是传入strlen函数,被强制转换为char*类型 // 每次取出一个字节,10,a0,31,60,f7,7f,然后遇到字符串结束符。00也是字符串结束符,所以这里是6。 //紧接着10 a0 31 60 f7 7f 00 00后的8个字节就是&p+1的中存储的内容,从开头开始取,直到取到字符串结束符。不管什么时候取到字符串结束符,也与&p的长度没有关系 //此时&p与&p+1就没有联系 //有联系的情况: //p变量的地址(&p):0x11 22 7f f7 60 31 a0 10 //因为内存中采用小端存储形式,也就是低位低地址。所以&p存储到内存中是:10 a0 31 60 f7 7f 22 11。 //本来使用指针来取,则是倒着取出来。但是传入strlen函数,被强制转换为char*类型 //从开头开始取,每次取出一个字节,10,a0,31,60,f7,7f,22,11,没有遇到字符串结束符。 //紧接着10 a0 31 60 f7 7f 22 11后的8个字节就是&p+1的中存储的内容,继续取,直到取到字符串结束符。 //不管什么时候遇到结束符,此时生成的随机值关系:&p的随机值减去8就是&p+1的随机值。 //因为是在64位平台下,所以是减去8。如果是32平台下,那么地址的长度是4个字节,就是减去4。 //p[0]找到a,&p[0]取出a的地址,&p[0]+1,也就是b所在的地址,然后取到字符串结尾。应该是6-1=5 printf("%dn",strlen(&p[0]+1));//5 /
杨氏矩阵
#include void find_num(int arr[3][3],int a,int b,int num){ int x = 0; int y = b-1;//把num与每一行的最后一列上的数进行比较 //只要行数x<行数,就说明还没到最后一行;并且y≥0,说明还没到第一列。就可以继续寻找 while(x= 0) { //如果num比这一行最后一个数都大, 说明比这一行所有的数都大。 if(arr[x][y] < num) { x++; //x+1,与下一行比较 } else if(arr[x][y] > num) {//bum比这一行最后一个数大,说明num在这个数的左边。 y--;//与倒数第二个、第三个...比较 } else { //运行到这里,说明找到了,此时这个数与arr[x][y]相等 //输出下标 printf("这个数字所在下标是:%d %dn",x,y); //找到之后结束方法 return; } } //如果循环结束都没有找到,说明矩阵中没有这个数,返回0。 printf("没有这个数n");}int main(){ int arr[3][3] = {1,2,3,4,5,6,7,8,9}; //查找一个数字,比如说找7 int k = 7; find_num(arr,3,3,k);// //遍历数组查找——时间复杂度=o(N),不能使用这种方法// int i,j;// for(i=0 ; i<3 ; i++)// {// for(j=0 ; j<3 ; j++)// {// if(arr[i][j] == 7){}// }// } return 0;}
找到之后,如何在main中就可以打印出找到的数字的下标?
#include int find_num(int arr[3][3],int* px,int* py,int num){ int x = 0; int y = *py-1;//把num与每一行的最后一列上的数进行比较 //只要行数x<行数,就说明还没到最后一行;并且y≥0,说明还没到第一列。就可以继续寻找 while(x<*px && y>= 0) { //如果num比这一行最后一个数都大, 说明比这一行所有的数都大。 if(arr[x][y] < num) { x++; //x+1,与下一行比较 } else if(arr[x][y] > num) {//bum比这一行最后一个数大,说明num在这个数的左边。 y--;//与倒数第二个、第三个...比较 } else { //找到后将x与y,将其值保存到指针指向的变量,并且返回1 *px = x; *py = y; return 1; } } return 0;}int main(){ int arr[3][3] = {1,2,3,4,5,6,7,8,9}; //查找一个数字,比如说找7 int k = 7; //如何获取到坐标呢? //传入指针进去,这样操作的就是同一数了 int x = 3; int y = 3; int ret = find_num(arr,&x,&y,k); if(ret == 1) { printf("找到了n下标是:%d,%d",x,y); } else { printf("没这个数n"); } return 0;}
声明一个指向函数指针数组的指针
字符串左旋
#include #include void left_rotate(char* str,int k){ int i,j; //求字符串长度,也就是传入的数组中有多少个字符 int n = strlen(str); //要左旋几个字符,就循环几次 for(i=0 ; i
自己想出来的(改变了首元素指针指向,不推荐使用)
#include #include void left_rotate(char* str,int k){ int i,j; //求字符串长度,也就是传入的数组中有多少个字符 int n = strlen(str); //要左旋几个字符,就循环几次。 for(i=0 ; i#include #include reverse(char* left,char* right){ //断言:left和right不为空指针。如果他们不是空,则为非0;如果为NULL,则是0,assert(0)就会不会往下运行,并给出错误信息。 assert(left); assert(right); while(leftn) { k -= n;//如果k大于字符串长度,就减去n,直到k
判断某个字符串是否由另一个字符串旋转而来
#include #include int is_rotate(char* str1,char* str2){ int i,j; //求字符串长度,也就是传入的数组中有多少个字符 int n = strlen(str1); //有多少个字符,就左旋多少次,每旋转一次判断一下是否相等。 for(i=0 ; i
另一种方法
#include #include int is_rotate(char* str1,char* str2){ //如果两个字符串长度不相等,则直接返回0 if(strlen(str1) != strlen(str2)) { return 0; } //1、str1字符串的后面追加一个str1 //AABCD变为AABCDAABCD strcat(str1,str1); //判断str2是否是str1中的字符串。如果是,则返回首次出现的指针,如果不是,则返回NULL。所以我们直接返回 return strstr(str1,str2);}int main(){ //将arr1开辟的空间变大一点 char arr1[20] = "AABCD"; char arr2[] = "CDAAB"; int ret = is_rotate(arr1,arr2); if(ret == 0) { printf("不是旋转而来"); } else { printf("是旋转而来"); } return 0;}
test.c中包括如下语句
//文件定义的四个变量,哪个不是指针类型? 变量b不是//定义宏,使用的时候,INT_PTR 会被int*替换掉#define INT_PTR int*//typedef是将int*类型,重命名为int_ptr了typedef int* int_ptr;//INT_PTR 会被int*替换掉 就成为:int * a,b;//注意这里的*表示a是指针变量,所以*给了a,而b没有*,所以a是int*指针类型,而b是int类型//所以定义指针变量的时候,不能使用连续声明。如果要连续声明,则需要int *a,*b;这样a和b就都是int*指针类型了。INT_PTR a,b;//typedef是将int*类型,重命名为int_ptr了//所以这里c与d都是int_ptr类型,也就是int*指针类型。int_ptr c,d;