指针数组🫧
指针数组是用来存放指针的数组。
指针数组模拟二维数组
用指针数组里的每一个指针(元素)指向一个一维数组(一行)。
#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
才会停止读取。
注意:
- 【本质是字符指针】对于字符指针来说,内容相同的字符串常量会被放到同一地址,即不会为它们开辟两块不同的空间,只有常量会这样哦。但如果把【本质是数组】内容相同的字符串常量放到两个不同的数组里,它们会被放到不同的地址中。
str1[] = "LOVE YOU";
str2[] = "LOVE YOU";
char* str3 = "LOVE YOU";
char* str4 = "LOVE YOU";
str1
和str2
的地址不同。但str3
和str4
的地址相同。
- 字符串常量不可以修改,即不能“重新赋值”。所以用
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等】。
如果实参是数组 ,那么形参可以写成数组或指针;如果实参传过来的是地址,那么形参只能写成指针的形式接收。
理解二维数组传参本质:
- 二维数组的每个元素是一个一维数组,所以二维数组的首元素是第一行。
- 数组名是数组首元素的地址。
- 二维数组传参时,实参会写成形如
被调用函数名(二维数组名);
,如test(arr);
。 - 实参是传递过去的东西,形参是用来接收实参的东西。
函数指针变量🫧
函数指针变量是用来存放函数地址的,将来可以通过地址调用这个函数。
函数名就是函数的地址,也可以通过&函数名
来获取函数的地址。
函数指针变量形如指向函数的返回类型 (*函数指针变量名) (指向函数的形参)
,初始化形如函数指针变量 = 函数地址
。
初始化:
#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);//简化后
能量站😚
比较是没有价值的,因为别人是别人,自己是自己。世界上的每个人都有其特质,只有这些特质得到承认,才能产生作为人的存在感。
❤️❤️❤️ 恭喜! 恭喜! 闯关成功! ❤️❤️❤️