数组指针、指针数组、常量指针、指针常量、函数指针、指针函数

在C语言中,常常有一些相似的名词出现,但其实代表的是不同的含义。本文仅阐述自己对这些概念的理解和分享。

1.数组指针与指针数组的异同点

2.常量指针和指针常量的异同点

3.函数指针和指针函数的异同点

接下来我将用一段程序来说明这6者之间的关系,示例程序已在visual studio中验证完成并附在文末。

//数组指针:指向数组的指针 int(*ptr)[5]
//指针数组:一个数组,元素都是指针 int *arr[5]
//常量指针:指向常量的指针,指向内容是常量,内容无法修改,地址可以修改 const int *ptr
//指针常量:指针本身是常量,指向不能改变,可以修改内容,地址无法修改 int *const ptr
//函数指针:指向函数的指针,通过调用该指针来使用该函数,返回类型(*函数名)(参数列表)
//指针函数:返回指针的函数,返回类型 *函数名 (参数列表)

 

数组指针:是一个指向整个数组大小的指针;对指针进行加减运算时,移动的是整个数组的大小;常用在二维数组的传递中。

语法类型:数据类型(*指针名)[]。

image

 

指针数组:是一个元素都是指针的数组;常用于存储字符串数组;每个指针可以指向不同长度的数据。

语法类型:数据类型 *指针名[]。

image

 常量指针:指向常量的指针,指向内容是常量;内容不能修改,地址可以修改(可以通过修改地址间接修改内容);常用于函数参数,防止修改数据。

语法形式:const 数据类型 * 指针名;数据类型 const  * 指针名。

image

 

指针常量:指针本身是常量,指向不能改变;可以修改内容,地址无法修改;必须要在定义时初始化 。

语法:数据类型* const 指针名。

image

特殊类型:常量指针常量:const 类型名 * const 指针名;地址和内容都无法改变。

 

函数指针:指向函数的指针,通过调用该指针来使用该函数;常用于回调函数、函数表;可以指向匹配签名的任何函数。

语法类型:返回类型 (*函数名)(参数列表)。

image

指针函数:返回值是指针类型的函数。

语法类型:返回类型 *函数名 (参数列表)。

image

 

记忆技巧:

1.数组指针和指针数组 :()中有*指针名;是指针,指向数组;无(),指针名和[]结合,是数组,元素是指针。

2.常量指针和指针常量:const 在*左边,指向的值不变,是常量指针;const在*右边,指向的地址不变,是指针常量。tips:指针常量需初始化。

3.函数指针和指针函数:()中有*指针名;是指针,指向函数;无(),指针名和(参数列表)结合,是函数,返回值是指针。
总结:()中的优先级最高,若()中有*指针名,则是指针,后面的属性定义指向数组or函数;无()保护*指针名,则是一种具体的类型。

应用场景:

1.数组指针:二维数组作为函数参数,矩阵处理。

2.指针数组:字符串数组,命令行参数。

3.常量指针:函数参数保护,防止意外修改,只可读,不可修改。

4.指针常量:硬件寄存器地址访问,固定地址访问,可以修改内容。

5.函数指针:回调函数,函数表。

6.指针函数:工厂模式,动态内存分配。

注意事项:

1.数组指针和指针数组声明注意()的位置。

2.常量指针只是限制通过指针修改数据,但不限制修改指针变量。

3.指针函数不要返回局部变量的地址(栈内存会在函数返回后释放)。

4.函数指针需要和所指向函数的签名完全匹配。

示例程序:

#include<stdio.h>

int add(int a, int b);
int sub(int a, int b);
int* funa(int* p);
int main()
{
	//数组指针:指向数组的指针        int(*ptr)[5]
	//指针数组:一个数组,元素都是指针 int *arr[5]
	//常量指针:指向常量的指针,指向内容是常量,内容无法修改,地址可以修改 const int *ptr
	//指针常量:指针本身是常量,指向不能改变,可以修改内容,地址无法修改 int *const ptr
	//函数指针:指向函数的指针,通过调用该指针来使用该函数,返回类型(*函数名)(参数列表)
	//指针函数:返回指针的函数,返回类型 *函数名 (参数列表)

	//1.数组指针:指向数组的指针        int(*ptr)[5]
	printf("数组指针\n");
	int arr[5] = { 1,2,3,4,5 }; 
	int i;
	int(*ptr1)[5] = arr; //数组名就是数组地址 取地址方式1
	for (i = 0; i < 5; i++)
	{
		printf("%d\n", (*ptr1)[i]);
	}
	int(*ptr2)[5] = &arr; //数组名就是数组地址 取地址方式2
	for (i = 0; i < 5; i++)
	{
		printf("%d\n", (*ptr2)[i]);
	}
	printf("数组指针\n");
	//2.指针数组:一个数组,元素都是指针 int *brr[5]
	printf("指针数组\n");
	int a = 1, b = 2, c = 3;
	int *brr[3] = {&a,&b,&c};
	for (i = 0; i < 3; i++)
	{
		printf("%d\n", *brr[i]);
	}
	for (i = 0; i < 3; i++)
	{
		printf("%p\n", brr[i]);
	}
	printf("%p\n", &a);
	printf("%p\n", &b);
	printf("%p\n", &c);
	printf("指针数组\n");

	//3.常量指针:指向常量的指针,指向内容是常量,内容无法修改,地址可以修改 const int *ptr
	//可以通过修改地址来修改值
	int ab = 100;
	int bc = 200;
	const int ac = 10;
	const int *ptr3 = &ab; //指向ab,但通过指针无法修改ab的值
	printf("常量指针\n");
	printf("%d\n", *ptr3);
	printf("%p\n", ptr3);
	//*ptr3 = 30;
	ptr3 = ∾
	printf("%p\n", &ab);
	printf("%p\n", &ac);
	printf("%d\n", *ptr3);
	printf("%p\n", ptr3);
	ptr3 = &bc;
	printf("%d\n", *ptr3);
	printf("%p\n", ptr3);
	printf("常量指针\n");

	//4.指针常量:指针本身是常量,指向不能改变,可以修改内容,地址无法修改 int *const ptr
	int abc = 99, bac = 88, aaa=55, bbb=66;
	printf("指针常量\n");
	printf("%p\n", &bac);
	printf("%p\n", &abc);
	int* const ptr4 = &abc;
	*ptr4 = 77;
	printf("%p\n", ptr4);
	printf("%d\n", *ptr4);
	*ptr4 = aaa;
	printf("%p\n", ptr4);
	printf("%d\n", *ptr4);
	*ptr4 = bbb;
	printf("%p\n", ptr4);
	printf("%d\n", *ptr4);

	printf("指针常量\n");
	//ptr4 = &bac;
	//5.函数指针:指向函数的指针 返回类型(*func)(参数列表)
	printf("函数指针\n");
	int abcd = 0;
	int(*func)(int a, int b);
	func = NULL;
	printf("%p\n", add);
	printf("%p\n", func);
	func = &add;
	printf("%p\n", func);
	abcd = func(3, 4);
	printf("%d\n", abcd);
	printf("%p\n", func);
	printf("%p\n", sub);
	func = sub;
	printf("%p\n", sub);
	printf("%p\n", func);
	abcd = sub(9, 4);
	printf("%d\n", abcd);
	printf("函数指针\n");
	//6.指针函数:返回指针的函数,返回类型 *函数名 (参数列表)
	printf("指针函数\n");
	int aabb = 123;
	int *ptr5;
	int* ptr6= funa(&aabb);
	printf("%p\n", &aabb);
	printf("%p\n", funa);
	ptr5 = funa(&aabb);
	printf("%p\n", ptr5);
	printf("%p\n", ptr6);
	printf("%d\n", *ptr5);
	printf("%d\n", *ptr6);
	printf("指针函数\n");

	return 0;

}

int add(int a, int b)
{
	return a + b;
}
int sub(int a, int b)
{
	return a - b;
}

int* funa(int *p)
{
	return p;
}

  

posted @ 2026-02-08 21:27  来碗回锅肉盖饭  阅读(61)  评论(0)    收藏  举报