目录
一、指针操作二维字符型数组
char s[][10] = {"hello","world","china"};
1.定义指针
与二位整型数组相同
char (*p)[10] = s; //p指向二维数组s
2.访问数组中的字符串
由于字符型看二维数组大的行数所以访问到*(p+i)每一行就可以。
给字符串排序,通过选择排序的方式
#include <stdio.h>
#include <string.h>
void printfArray(char (*p)[10],int row)
{
int i=0;
for(i=0;i<row;++i)
{
printf("%s\n",*(p+i));
}
}
void choose(char (*p)[10],int row)
{
int i=0;
int j=0;
for(i=0;i<row-1;++i)
{
for(j=i+1;j<row;++j)
{
if(strcmp(*(p+j),*(p+i))<0)
{
char temp[10];
strcpy(temp,*(p+j));
strcpy(*(p+j),*(p+i));
strcpy(*(p+i),temp);
}
}
}
}
int main(void)
{
char a[][10]={"hello","help","hell"};
int row=sizeof(a)/sizeof(a[0]);
printfArray(a,row);
choose(a,row);
printf("---------------\n");
printfArray(a,row);
return 0;
}
strcmp(*(p+j),*(p+i)),因为是字符串所以使用srtcmp函数进行比较。
char temp[10],因为要存储字符串,所以定义的是一维字符型数组。
strcpy(temp,*(p+j)),字符串不能直接赋值,通过复制过去。
3.指针数组
char s[10] = "hello";//存放字符串数据
char s[10]; //s的数据类型 char[10]
char[10] s1[3]; //二维数组 //此时的二维数组的元素 是一个一维字符型数组
//可以认为是定义一个存放 字符串 的一维数组
char *p = "hello"; //p的类型 char *
//char *的指针变量p 相当于代表一个字符串,也就是p的值是这个字符串在字符串常量区的地址
char *p1 = "hello";
char *p2 = "world";
char *p3 = "china";
char* pstr[3]= {"hello","world","china"}; //数组 --- 数组中存放是 各个字符串的地址,地址就是指针
//存放着地址数据的数组 --- 指针的数组 ---指针数组
4.定义一个指针指向指针数组
char **q = pstr; //q 二级指针
#include <stdio.h>
#include <string.h>
void printfArray(char **p,int len)
{
int i=0;
for(i=0;i<len;++i)
{
printf("%s\n",*(p+i));
}
}
char * max_str(char **p,int len)
{
char *max=*p;
int i=0;
for(i=1;i<len;++i)
{
if(strcmp(max,*(p+i))<0)
{
max=*(p+i);
}
}
return max;
}
void reverse(char **begin,char **end)
{
while(begin<end)
{
char *temp=*begin;
*begin=*end;
*end=temp;
begin++;
end--;
}
}
void insert(char **p,int len)
{
int i=0;
int j=0;
for(i=1;i<len;++i)
{
char *temp=*(p+i);
j=i;
while(j>0 && strcmp(*(p+j-1),temp)>0)
{
*(p+j)=*(p+j-1);
--j;
}
*(p+j)=temp;
}
}
void popo(char **p,int len)
{
int i=0;
int j=0;
for(i=1;i<len;++i)
{
for(j=0;j<len-i;++j)
{
if(strcmp(*(p+j),*(p+j+1))>0)
{
char *temp=*(p+j);
*(p+j)=*(p+j+1);
*(p+j+1)=temp;
}
}
}
}
int main(void)
{
char* p[]={"hello","world","china"};
int len=sizeof(p)/sizeof(p[0]);
int i=0;
for(i=0;i<3;++i)
{
printf("%s\n",p[i]);
}
printf("-------------\n");
popo(p,len);
printfArray(p,len);
return 0;
}
char *max=*p;存储的是指针,所以需要定义指针来存储这个指针数组中的值,也就是字符串的地址。
strcmp(max,*(p+i)) //strcmp函数原型中的形参就是指针形式,需要的就是地址,而max就是地址,里面存储的是字符串的地址,*(p+i)找到指针数组中存储的字符串地址。拿下图举例因为存放字符串地址的内存空间自己也有地址(0x6000),所以需要进行*运算才能,取出字符串地址(0x1000)。然后函数strcmp通过地址找到字符串进行比较。
5.指针数组的应用
#include <stdio.h>
int main(int argc, const char *argv[])
{
printf("argc = %d\n",argc);
int i=0;
for(i=0;i<argc;++i)
{
printf("argv[%d]=%s\n",i,argv[i]);
}
return 0;
}
const char *argv[]就是指针数组,在系统操作时,命令行输入命令,传到main函数的形参中。
argc是字符串个数;
argv[]存储的是字符串。
二、指针 + 函数
通过指针 的方式 来调用函数
函数名 --- 代表函数的入口地址
int add(int a,int b) // 函数
// add函数名 - 代表函数的入口地址
// 函数名对应的数据类型 :int (int a,int b) //函数类型
// 代表一类函数
// 返回值为int型,带有两个int型的形参变量的一类函数
说明:
1.可以定义一个函数类型的指针变量来保存函数的入口地址
2.有了这个指针变量可以通过指针变量进行函数调用,这称为回调函数 callback
回调函数 --- 通过函数指针调用函数 就是回调
#include <stdio.h>
int func1(int n)
{
return n;
}
int func2(int n)
{
return n*n;
}
void choose(int *a,int len,int(*p)(int))
{
int i=0;
int j=0;
for(i=0;i<len-1;++i)
{
for(j=i+1;j<len;++j)
{
if(p(a[j])<p(a[i]))
{
int temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
}
}
void printfArray(int *a,int len)
{
int i=0;
for(i=0;i<len;++i)
{
printf("%d ",a[i]);
}
putchar('\n');
}
int main(void)
{
int a[]={2,8,6,1,7,-4,-5};
int len=sizeof(a)/sizeof(a[0]);
choose(a,len,func2);
printfArray(a,len);
return 0;
}
在choose(a,len,func2);函数中又调用了func函数,通过int(*p)(int)函数指针调用函数,发生了函数回调。
#include <stdio.h>
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 processData(int a,int b,int(*pfunc)(int ,int))
{
printf("%d\n",pfunc(a,b));
}
int main(void)
{
int a=0;
int b=0;
scanf("%d %d",&a,&b);
processData(a,b,add);
return 0;
}
同样在processData中,通过int(*pfunc)(int ,int),实现函数回调,又调用add函数。