学习C语言 8.8 指针

目录

一、指针操作二维字符型数组

1.定义指针

2.访问数组中的字符串

3.指针数组    

4.定义一个指针指向指针数组

5.指针数组的应用

二、指针 + 函数


 

一、指针操作二维字符型数组

 

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通过地址找到字符串进行比较。

f52eeb9caa314add87d8356e0389afaa.png

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[]存储的是字符串。

bd1b038a19be483b86a11f8473d28bf6.png

 

二、指针 + 函数

通过指针 的方式 来调用函数 


函数名 --- 代表函数的入口地址 

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函数。

 

  • 15
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值