本文详细的记录了,指针与数组、函数和const之间不同的关系。也就是我们口中的特殊指针。
目录
前言
因为记不住,所以写了篇笔记给自己看
正文
1、空指针(Null指针)
空指针是一个特殊的指针值,表示不指向任何有效的内存地址,可以使用Null表示空指针。空指针通常用于初始化指针变量,或者作为指针的特殊值来表示指针未指向有效的对象。
例如:
int *p = Null // 空指针
if (p==Null)
printf("This is Null")
2、野指针
野指针是指指针变量指向非法、未定义或已释放的内存地址。使用野指针会导致未定义的行为,可能引发程序崩溃或产生难以调试的错误。为了避免野指针问题,应始终在使用指针之前进行初始化,并及时将指针置为NULL或合法的地址。
例如:
int* p; // 未初始化的指针(野指针)
*p = 10; // 试图在未分配内存的情况下写入数据,可能导致程序崩溃
3、 指向指针的指针
指向指针的指针是指一个指针变量存储另一个指针变量的地址。通过使用指向指针的指针,可以实现对指针的间接访问和修改。
例如:
int a = 10;
int* ptr = &a;
int** pp = &ptr; // 指向指针的指针
printf("%d\n", **pp); // 输出a的值
4、 常量指针和指针常量
1、常量指针
是指指针指向的内存内容不能通过指针进行修改,但可以指向其他对象。
例如:
int i,j;
// 当const在*号的右边表示常量指针
const int *p = &i; // ==> 等价于 int const *p = &i; 表示将*p作为常量,所以不能修改*p
*p = 23; // False 常量指针不能通过指针去修改变量的值
i = 23; // True
*p = &j; // True 常量指针可以指向其他的变量地址
2、指针常量
是指指针本身的值(即地址)一旦得到就不能被修改,但可以通过指针修改所指向的对象。
例如:
int i,j;
// const在*号的右边表示指针的值不能修改
int *const p = &i; // 表示将p设置为常量,所以p不能被修改
*p = 23; // True
i = 23; // True
*p = &j; // False 指针常量那个一旦赋值就不能进行修改
5、指针数组与数组指针
1、指针数组
指针数组是一个数组,数组中的每一个元素都是指针。这些指针可以指向任意类型的数据,包括其他的数组、结构体等。
指针数组的声明方式为:指针类型 数组名[元素个数]; 比如:int* arr[10]
例如:
int c[][5] = { { 1,2,3,4 }, {1,45,5,12} };
int* arr[2] = {c[0],c[1]}; // 初始化指针数组,中的每一个元素都指向二维数组c的元素地址
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 5; j++)
printf("%d", (*(arr+i))[j]); // 输出二维数组c的值
}
2、数组指针
数组指针是一个指针,它指向一个数组。
数组指针的声明方式为:指针类型 (*指针变量名)[元素个数];比如:int *(p)[10]是指向一个包含10个整数数据的数组的指针
例如:
int c[][5] = { { 1,2,3,4 }, {1,45,5,12} };
int (*p)[2] = c; // 定义一个指向包含3个整型数据的数组的指针
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 5; j++)
printf("%d\t", (*(p+i))[j]); // 输出二维数组的值
}
6、函数指针与指针函数
1、函数指针
函数指针是指向函数的指针变量。它可以存储函数的地址,并且可以通过该指针调用函数。通过函数指针,我们可以将函数作为参数传递给其他函数,或者在运行时动态的选择要调用的函数。函数指针的声明方式类似与函数声明,只需要在函数名面前加上一个*符号。
例如:
int (*func)(int,int); // 函数指针声明
int add(int a, int b){
return a+b;
}
int main(){
func = &add; // 将函数地址传递给函数指针
int result = (*func)(3,4); // 通过函数指针调用函数
printf("%d",result);
return 0;
}
2、 指针函数
指针函数是返回值为指针的函数。它的返回值是一个指针类型,可以指向函数内部定义的局部变量或动态分配的内存。
例如:
int* create(int size) {
int* p = malloc(size * sizeof(int)); // 创建size个的int型内存空间,并让p指向它
return p;
}
int main() {
int* q = create(5); // 调用指针函数,返回指向堆内存的指针,并是q指向它
free(q); // 释放动态分配的内存
return 0;
}
总结
到底谁发明的这东西啊,弯弯绕绕,记都记不住,不然都不用写着玩意。