C语言基础-指针(下)

1、数组与指针,函数封装

数组名即为地址(指针)

#include <stdio.h>

void initArray(int *parr,int size)//*为标记作用
{
	int i;
	for(i =0;i<size;i++)
	{
		printf("请输入第%d个元素的数据:\n",i+1);
		scanf("%d",parr++);
	}
}

void printArray(int *parr,int size)//*为标记作用
{
	int i;
	for(i =0;i<size;i++)
	{
		printf("%d",*parr++);//*为取值作用
	}
}

int main()
{		
	int arry[5];
	int size = sizeof(arry)/sizeof(arry[0]);
	initArray(arry,size);
	printArray(&arry[0],size);//实际参数:数组的首地址/数组名/首个元素的地址
	return 0;
}

2、数组翻转函数封装

#include <stdio.h>

void initArray(int *parr,int size)//*为标记作用
{
	int i;
	for(i =0;i<size;i++)
	{
		printf("请输入第%d个元素的数据:\n",i+1);
		scanf("%d",parr++);
	}
}

void revangeArry(int *parr,int size)
{
	int i,j;
	int temp;
	for(i = 0;i<size/2;i++)
	{
		j = size-1-i;
		temp = parr[i];			//temp = *(parr+i);      地址偏移,paar为数组首元素的地址
		parr[i] = parr[j];		//*(parr+i) = *(parr+j); 这几行*为取值作用
		parr[j] = temp;			//*(parr+j) = temp;
	}
}

void printArray(int *parr,int size)//*为标记作用
{
	int i;
	for(i =0;i<size;i++)
	{
		printf("%d",*parr++);//*为取值作用
	}
}

int main()
{		
	int arry[5];
	int size = sizeof(arry)/sizeof(arry[0]);
	initArray(arry,size);
	printArray(&arry[0],size);//实际参数:数组的首地址/数组名/首个元素的地址
	revangeArry(&arry[0],size);
	printArray(&arry[0],size);
	return 0;
}

3、二维数组地址(指针)

父子数组

int a[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};

a是二维数组名,父数组的名,父数组的地址————行

子数组的名(地址):a[0]、a[1]、a[2]————————列

问:a+1偏移了多少?a[0]+1偏移了多少?

答:a+1从1到5,16个字节

        a[0]+1从1到2;4个字节

!!!数组名也是数组首元素地址

        对于二维数组,a[1](子数组的名)=&a[1][0](子数组的第一个元素取地址)

        a[2]=&a[2][0]

首地址:①数组名;②首个元素的地址;

*a = a[0]       *(a+1) = a[1]         //此处*为取值作用

实例:

#include <stdio.h>

int main()
{
	int arr[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
	
	printf("arr是父数组地址:%p,偏移1后为:%p\n",arr,arr+1);
	printf("arr[0]是子数组地址:%p,偏移后1为:%p\n",arr[0],arr[0]+1);
	printf("arr[0]是子数组地址:%p,偏移1后为:%p\n",*(arr+0),*(arr+0)+1);//对二维数组的第一个元素取值即为{1,2,3,4},也就是该元素的地址
}

运行结果:

arr是父数组地址:000000000061FDF0,偏移1后为:000000000061FE00
arr[0]是子数组地址:000000000061FDF0,偏移后1为:000000000061FDF4
arr[0]是子数组地址:000000000061FDF0,偏移1后为:000000000061FDF4

②、遍历数组

#include <stdio.h>

int main()
{
	int arr[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
	int i;
	int j;
	for(i=0;i<3;i++)
	{
		for(j=0;j<4;j++)
		{
			printf("地址:%p;数据:%d\n",&arr[i][j],arr[i][j]);
			printf("地址:%p;数据:%d\n",arr[i]+j,*(arr[i]+j));
			printf("地址:%p;数据:%d\n",*(arr+i)+j,*(*(arr+i)+j));
			printf("=============\n");
		}
		printf("\n");
	}
	
}

运行结果:

地址:000000000061FDE0;数据:1
地址:000000000061FDE0;数据:1
地址:000000000061FDE0;数据:1
=============
地址:000000000061FDE4;数据:2
地址:000000000061FDE4;数据:2
地址:000000000061FDE4;数据:2
=============
地址:000000000061FDE8;数据:3
地址:000000000061FDE8;数据:3
地址:000000000061FDE8;数据:3
=============
地址:000000000061FDEC;数据:4
地址:000000000061FDEC;数据:4
地址:000000000061FDEC;数据:4
=============

地址:000000000061FDF0;数据:5
地址:000000000061FDF0;数据:5
地址:000000000061FDF0;数据:5
=============
地址:000000000061FDF4;数据:6
地址:000000000061FDF4;数据:6
地址:000000000061FDF4;数据:6
=============
地址:000000000061FDF8;数据:7
地址:000000000061FDF8;数据:7
地址:000000000061FDF8;数据:7
=============
地址:000000000061FDFC;数据:8
地址:000000000061FDFC;数据:8
地址:000000000061FDFC;数据:8
=============

地址:000000000061FE00;数据:9
地址:000000000061FE00;数据:9
地址:000000000061FE00;数据:9
=============
地址:000000000061FE04;数据:10
地址:000000000061FE04;数据:10
地址:000000000061FE04;数据:10
=============
地址:000000000061FE08;数据:11
地址:000000000061FE08;数据:11
地址:000000000061FE08;数据:11
=============
地址:000000000061FE0C;数据:12
地址:000000000061FE0C;数据:12
地址:000000000061FE0C;数据:12
=============

总结:

二维数组a的有关指针

表示形式 含义 a 二维数组名,指向一维数组a[0],即0行首地址 a[0],*(a+0),*a 0行0列元素地址 a+1,&a[1] 1行首地址 a[1],*(a+1) 1行0列元素a[1][0]的地址 a[1]+2,*(a+1)+2,&a[1][2] 1行2列元素a[1][2]的地址 *(a[1]+2),*(*(a+1)+2),a[1][2] 1行2列元素a[1][2]的值

4、数组指针

定义一个指针,指向一个数组

数组指针真正意义上等同于二维数组名

也就是说定义一个指针,就是子数组的地址

格式:

        int arr[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};

        int(*p)[4];

        p = arr;

//数组指针遍历数组
#include <stdio.h>

int main()
{
	int arr[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
	int i;
	int j;
	int (*p)[4];
	p = arr;
	for(i=0;i<3;i++)
	{
		for(j=0;j<4;j++)
		{
			printf("%d\n",*(*(p+i)+j));
			
		}
		
	}
	
}

练习:二维数组,输入行列,取值

//二维数组,输入行列,取值
#include <stdio.h>

int findResult(int (*p)[5],int hang,int lie)
{
	int data;
	data = *(*(p+hang)+lie);
	return data;
    //return p[hang][lie];
}

void tipsInputHangLie(int *pm,int *pn)
{
	printf("请输入行列值:");
	scanf("%d%d",pm,pn);
	puts("输入完成!");
}

int main()
{
	int arr[3][5] = {{1,2,3,4,1},{5,6,7,8,1},{9,10,11,12,1}};
	int ihang,ilie;
	int data;
	
	//1、提示用户输入行列值
	tipsInputHangLie(&ihang,&ilie);
	//2、找出对应的那个数
	data = findResult(arr,ihang,ilie);
	//3、打印出来
	printf("第%d行第%d列的数为%d\n",ihang,ilie,data);
}

5、函数指针

函数地址:如果在程序中定义了一个函数,在编译时,编译系统为函数代码分配了一段存储空间,这段存储空间的起始地址(又称入口地址)称为这个函数的指针。

函数名即为地址。

如何定义一个函数指针变量?                                                                                                             int a —— int *p               char c —— char *p             int getData(int a,int b) —— int(*p)(int a,int b)

使用函数指针                                                                                                                                     

//函数指针
#include <stdio.h>

int inDate(int data)
{
	return ++data;
}

void printWelcome()
{
	puts("欢迎!");
}

int main()
{	
	//定义函数指针
	void(*p1)();
	int(*p2)(int data);
	
	//指向函数
	p1 = printWelcome;
	p2 = inDate;
	
	//调用
	(*p1)();
	printf("p2测试:%d\n",(*p2)(10));
	
	return 0;
}

练习:有两个整数a和b,由用户输入1,2或3。如输入1,程序给出最大者,输入2,给出最小者,输入3,求ab之和。

//有两个整数a和b,由用户输入1,2或3。
//如输入1,程序给出最大者,
//输入2,给出最小者,
//输入3,求ab之和。
#include <stdio.h>

int getMax(int data1,int data2)
{
	return data1>data2?data1:data2;
}

int getMin(int data1,int data2)
{
	return data1>data2?data2:data1;
}

int getSum(int data1,int data2)
{
	return data1+data2;
}

int dataHand(int data1,int data2,int (*pfunc)(int data1,int data2))
{
	int result;
	result = (*pfunc)(data1,data2);
	return result;
}
int main()
{
	int a = 1;
	int b = 2;
	int cmd;
	int result;
	
	//函数指针
	int (*pfunc)(int data1,int data2);
	
	printf("请输入:");
	scanf("%d",&cmd);
	switch(cmd)
	{
		case 1:
		pfunc = getMax;
		break;
		case 2:
		pfunc = getMin;
		break;
		case 3:
		pfunc = getSum;
		break;
		default:
		printf("输入错误!");
	}
	
	result = dataHand(a,b,pfunc);
	printf("result = %d\n",result);
	return 0;
}

6、指针数组

int *p[4];

是一个数组,数组的每一项都是一个指针变量

#include <stdio.h>

int main()
{
	int a = 1;
	int b = 2;
	int c = 3;
	int d = 4;
	
	int *p[4] = {&a,&b,&c,&d};//标识
	for(int i = 0;i<4;i++)
	{
		printf("%d ",*(p[i]));//p[i]是一个地址,对地址取值
	}
	return 0;
}

函数指针数组

//有两个整数a和b,求最大者、最小者、ab之和。
#include <stdio.h>

int getMax(int data1,int data2)
{
	return data1>data2?data1:data2;
}

int getMin(int data1,int data2)
{
	return data1>data2?data2:data1;
}

int getSum(int data1,int data2)
{
	return data1+data2;
}

int main()
{
	int a = 1;
	int b = 2;
	int result;
	
//函数指针数组
	int (*pfunc[3])(int ,int ) = {getMax,getMin,getSum};
	
	for(int i=0;i<3;i++)
	{
		result = (*pfunc[i])(a,b);
		printf("result = %d\n",result);
	}
	return 0;
}

7、指针函数

 函数的返回值为指针类型即地址

8、二级指针

#include <stdio.h>

int main()
{
	int data = 3;
	printf("data的地址为:%p\n",&data);
	
	int *p1 = &data;
	printf("p1保存data的地址为%p,数据是%d\n",p1,*p1);
	
	int **p2 = &p1;
	printf("p2保存p1的地址为%p,数据是%d\n",p2,**p2);
	
}

9、总结

各种指针的定义

①一个整型数:int a;

②一个指向整型数的指针:int *a;  (指针)

③一个指向指针的指针,它指向的指针指向一个整型数:int **a;   (二级指针)

④一个有10个整型数的数组:int a[10];   (数组 )

⑤一个有10个指针的数组,每个指针指向一个整型数:int *a[10];(指针数组)

⑥一个指向有10个整型数的数组的指针:int (*a)[10];(数组指针,数组每一项为整型数)

⑦一个指向指针的指针,被指向的指针指向一个有10个整型数的数组:int (**a)[10];

⑧一个指向指针的指针,该数组有10个整型指针:int *(*a)[10](数组指针,数组每一项为整型指针)

⑨一个指向函数的指针,该函数有一个整型参数并返回一个整型数:int (*a)(int);(函数指针)

⑩一个有10个指针的数组,每个指针指向一个函数,该函数有一个整型参数并返回一个整型数:int (*a[10])(int);  (函数指针数组,是一个数组)

⑪一个函数的指针,指向的函数的类型是有两个整型参数并且返回一个函数只针对函数,返回的函数指针指向有一个整型参数且返回整型数的函数:int(*(*a)(int,int))(int);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是C语言指针基础知识点: 1.指针的定义和初始化 指针是一个变量,其值为另一个变量的地址。定义指针变量时需要指定指针所指向的变量类型,然后使用*运算符来声明指针变量。指针变量的初始化可以为其赋值为另一个变量的地址,也可以将其初始化为NULL。 2.指针的运算 指针可以进行加、减、自增、自减等运算。指针加上一个整数n时,指向的地址会增加n个存储单元的大小,减去一个整数n时,指向的地址会减少n个存储单元的大小。 3.指针的比较 指针可以进行相等、大于、小于等比较运算。当两个指针指向同一个变量时,它们相等;当两个指针指向同一数组中的不同元素时,它们可以进行大小比较。 4.指针的类型转换 指针可以进行类型转换,但需要注意转换后的指针类型必须与指向的变量类型相同,否则可能会导致程序出错。 5.指针和数组 数组名本身就是一个指针,指向数组的第一个元素。可以使用指针来访问数组中的元素,也可以将指针作为函数参数来传递数组。 以下是一个例子,演示了指针的定义、初始化、运算和比较: ```c #include <stdio.h> int main() { int a = 10; int *p = &a; // 定义指向整型变量a的指针p printf("a的值为:%d\n", a); // 输出:a的值为:10 printf("p指向的变量的值为:%d\n", *p); // 输出:p指向的变量的值为:10 printf("p的值为:%p\n", p); // 输出:p的值为:0x7ffeeb5f8a2c printf("p+1的值为:%p\n", p+1); // 输出:p+1的值为:0x7ffeeb5f8a30 printf("p的地址为:%p\n", &p); // 输出:p的地址为:0x7ffeeb5f8a28 printf("p和&a的比较结果为:%d\n", p == &a); // 输出:p和&a的比较结果为:1 return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值