突破•指针三

指针数组🫧

指针数组是用来存放指针的数组

指针数组模拟二维数组

用指针数组里的每一个指针(元素)指向一个一维数组(一行)。

#include <stdio.h>

int main() 
{
	int arr1[] = { 1,2,3,4,5 };
	int arr2[] = { 2,3,4,5,6 };
	int arr3[] = { 3,4,5,6,7 };
	int* prr[] = { arr1,arr2,arr3 };
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 5; j++)
			printf("%d ", prr[i][j]);
		printf("\n");
	}
	return 0;
}

运行截图:
在这里插入图片描述
理解:
需要注意的是上述代码不是真是二维数组,因为它的每一行不是连续的。在这里插入图片描述

字符指针变量🫧

字符指针char*存放的是首字符的地址。
例如 char* pstr = "LOVE YOU."中存放的是L的地址,应用%c打印。
补充: %s是用来打印字符串的,遇到\0才会停止读取。
注意:

  1. 【本质是字符指针】对于字符指针来说,内容相同的字符串常量会被放到同一地址,即不会为它们开辟两块不同的空间,只有常量会这样哦。但如果把【本质是数组】内容相同的字符串常量放到两个不同的数组里,它们会被放到不同的地址中。
str1[] = "LOVE YOU";
str2[] = "LOVE YOU";
char* str3 = "LOVE YOU";
char* str4 = "LOVE YOU";

str1str2的地址不同。但str3str4的地址相同。

  1. 字符串常量不可以修改,即不能“重新赋值”。所以用const char* str = "TNT NICE"会更安全。
    关于const的使用可以参考突破•指针一
    在这里插入图片描述

数组指针变量🫧

数组指针变量是存放数组的地址,能够指向数组的指针变量
[]的优先级要高于*号的,所以必须加上()来保证p先和*结合。例如数组指针变量int (*p) [10]p先与*结合,表示它是一个指针变量,这个指针变量指向的是具体类型为int [10]的数组,所以[]中的数组元素个数不可以省略,即使指向的数组被定义为arr[] = {1,2,3,4,5,6,7,8,9,10}也不可以省略,因为计算机会计算出这个数组的元素个数,它的具体类型是确定的。

二维数组传参的本质🫧

二维数组传参的本质是传递了第一行这个一维数组的地址,那么二维数组传参【即实参是数组】,形参的部分可以写成数组,也可以写成指针形式。如传递arr[3][5] = { {1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15} },形参可以写成int 形参名[3][5],也可以写成int (*形参名)[5]【形参名随便取,例如a、arr或p等】。
如果实参是数组 ,那么形参可以写成数组或指针;如果实参传过来的是地址,那么形参只能写成指针的形式接收。
理解二维数组传参本质:

  1. 二维数组的每个元素是一个一维数组,所以二维数组的首元素是第一行。
  2. 数组名是数组首元素的地址。
  3. 二维数组传参时,实参会写成形如被调用函数名(二维数组名);,如test(arr);
  4. 实参是传递过去的东西,形参是用来接收实参的东西。

函数指针变量🫧

函数指针变量是用来存放函数地址的,将来可以通过地址调用这个函数。
函数名就是函数的地址,也可以通过&函数名来获取函数的地址。
函数指针变量形如指向函数的返回类型 (*函数指针变量名) (指向函数的形参),初始化形如函数指针变量 = 函数地址

初始化:

#include <stdio.h>

int Add(int x, int y)
{
	return x + y;
}

void test()
{

}

int main() 
{
	//初始化函数指针变量astrt
	int (*astr)(int, int) = Add;
	int (*astr)(int x, int y) = &Add;//x和y写上或省略都行
	//初始化函数指针变量vstrt
	void (*vstr)() = test;
	void (*vstr)() = &test;
	return 0;
}

作用:通过函数指针调用指针指向的函数。

#include <stdio.h>

int Add(int x, int y)
{
	return x + y;
}

int main() 
{
	int (*astr)(int, int) = Add;
	//使用
	printf("%d\n", astr(2,4));
	printf("%d\n", (*astr)(2,4));//两种形式都可以
	return 0;
}

运行截图:
在这里插入图片描述

typedef关键字🫧

作用:typedef 是用来类型重命名。
例如将int*重命名为ptr_t可以写成typedef int* ptr_t;,但对于数组指针类型和函数指针类型有点不同【新的类型名必须在*的右边】,如数组指针类型int(*)[5]重命名为parr_t可以写成typedef int(*parr_t)[5];,而函数指针类型void(*)(int)重命名为pf_t可以写成 typedef void(*pf_t)(int);

使用:将代码void (*signal(int , void(*)(int)))(int);简化

//简化void (*signal(int , void(*)(int)))(int);
typedef void(*pfun_t)(int);
pfun_t signal(int,pfun_t);//简化后

能量站😚

比较是没有价值的,因为别人是别人,自己是自己。世界上的每个人都有其特质,只有这些特质得到承认,才能产生作为人的存在感。
请添加图片描述
❤️❤️❤️ 恭喜! 恭喜! 闯关成功! ❤️❤️❤️

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值