C中指针数组和数组指针&指针函数和函数指针

本文深入解析C语言中指针数组与数组指针的概念及应用,包括它们的定义、使用场景及区别,同时介绍了函数指针与指针函数的特性与实例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

优先级:()>[]>*

[ ]和* 优先级:[]”的优先级比“*”要高

p1 先与“[]”结合,构成一个数组的定义,数组名为p1,int *修饰的是数组的内容,即数组的每个元素。那现在我们清楚,这是一个数组,其包含10 个指向int 类型数据的指针,即指针数组。

至于p2 就更好理解了,在这里“()”的优先级比“[]”高,“*”号和p2 构成一个指针的定义,指针变量名为p2,int 修饰的是数组的内容,即数组的每个元素。数组在这里并没有名字,是个匿名数组。那现在我们清楚p2 是一个指针,它指向一个包含10 个int 类型数据的数组,即数组指针。我们可以借助下面的图加深理解:

指针数组:首先它是一个数组,数组的元素都是指针,数组占多少个字节由数组本身决定。它是“储存指针的数组”的简称。

 

数组指针:首先它是一个指针,它指向一个数组。在32 位系统下永远是占4 个字节,至于它指向的数组占多少字节,不知道。它是“指向数组的指针”的简称。

 

数组指针和指针数组的区别(1)

 二、用法介绍:

1、数组指针(也称行指针)
定义 int (*p)[n];
()优先级高,首先说明p是一个指针,指向一个整型的一维数组,这个一维数组的长度是n,也可以说是p的步长。也就是说执行p+1时,p要跨过n个整型数据的长度。

如要将二维数组赋给一指针,应这样赋值:

int a[3][4];
int (*p)[4]; //该语句是定义一个数组指针,指向含4个元素的一维数组。
p=a;        //将该二维数组的首地址赋给p,也就是a[0]或&a[0][0]
p++;       //该语句执行过后,也就是p=p+1;p跨过行a[0][]指向了行a[1][]

所以数组指针也称指向一维数组的指针,亦称行指针。

2、指针数组

数组指针和指针数组的区别

18. C语言 -- 指针数组和数组指针

三、函数指针和指针函数

https://blog.youkuaiyun.com/dugudaibo/article/details/100054677

1、指针函数:

指针函数,简单的来说,就是一个返回指针的函数,其本质是一个函数,而该函数的返回值是一个指针。
声明格式为:*类型标识符 函数名(参数表)

int fun(int x,int y);

这种函数应该都很熟悉,其实就是一个函数,然后返回值是一个 int 类型,是一个数值。
接着看下面这个函数声明:

int *fun(int x,int y);

这和上面那个函数唯一的区别就是在函数名前面多了一个*号,而这个函数就是一个指针函数。其返回值是一个 int 类型的指针,是一个地址。

这样描述应该很容易理解了,所谓的指针函数也没什么特别的,和普通函数对比不过就是其返回了一个指针(即地址值)而已。

指针函数的写法:

int *fun(int x,int y);
int * fun(int x,int y);
int* fun(int x,int y);

示例代码:

#include <stdio.h>
#include <stdlib.h>
#include "vld.h"
typedef struct Data {
	int a;
	int b;
};
//指针函数 返回值是一个指向Data类型的地址
Data* f(int a, int b) {

	Data *data = (Data *)malloc(sizeof(Data));
	data->a = a;
	data->b = b;
	return data;
}
int main()
{
	//调用指针函数
	Data * myData = f(4, 5);
	printf("f(4,5) =%d\t%d\n", myData->a, myData->b);
	free(myData); //注意要释放子函数中 malloc申请的内存,在主函数中释放时,用free(myData),
				//而不是free(data),注意形参和实参的生命周期
	myData = NULL;
	return 0;
}

运行结果:

 

 

 

 

&lt;think&gt;嗯,用户想了解C/C++指针数组的声明,特别是int (*p)[4]的含义。首先,我需要回忆一下指针数组在C/C++中的不同声明方式。 首先,指针数组数组指针容易混淆。指针数组是一个数组,里面的每个元素都是指针。比如int *p[4],这应该是一个包含4个int指针数组。而数组指针则是一个指向数组指针,比如int (*p)[4],这里p是一个指针,指向一个包含4个int的数组。 用户的问题是关于int (*p)[4]的,所以这是数组指针。需要解释清楚p的类型是什么,如何初始化,以及如何访问元素。可能需要用例子来说明,比如p指向一个二维数组的行,此时p+1会跳过整个一维数组的大小,也就是4个int的长度。 还要注意指针数组的区别,避免用户混淆。比如int *p[4]int (*p)[4]的不同。另外,引用中的内容提到指针运算,比如*p++*(p++)的区别,这可能数组指针的移动有关联,可以结合例子说明。 然后,用户可能需要了解实际应用场景,比如在处理二维数组时,数组指针如何用于遍历行。或者动态分配内存时,如何声明这样的指针。需要确保语法正确,比如声明初始化方式,以及解引用时的操作。 另外,用户可能对指针引用的区别有疑问,但当前问题集中在指针数组数组指针,所以暂时不需要深入引用的话题,但可以提及参考中的指针与引用的区别引用[^3]。 最后,要检查是否有常见的错误或易错点需要提醒,比如括号的位置对语义的影响,还有数组指针函数参数中的使用,比如传递二维数组时可以用数组指针作为参数。 总结步骤应该是:先解释声明语法,说明类型,对比指针数组数组指针,给出示例代码,说明如何初始化访问元素,最后可能的应用场景注意事项。同时,根据用户提供的引用资料,引用相关的指针运算知识来加强解释,例如指针递增解引用的顺序[^1]。&lt;/think&gt;### C/C++数组指针声明 `int (*p)[4]` 的解析 #### 1. 语法结构解析 - **括号优先级**:`()` 改变了默认运算符优先级。`*` 与 `p` 先结合,表示 `p` 是一个指针。 - **类型说明**:`[4]` 位于类型 `int` 后,说明指针 `p` 指向的是一个**包含4个整数的数组**。 - **完整类型**:`p` 是**数组指针**,类型为 `int(*)[4]`,与普通指针 `int*` 有本质区别。 #### 2. 内存访问特性 - **指针运算**:对 `p` 进行 `+1` 操作时,地址增加 `4*sizeof(int)` 字节(例如:若 `int` 为4字节,则偏移16字节)。 - **解引用方式**:`*p` 得到的是整个数组,`(*p)[i]` 可访问数组第 `i` 个元素。 ```c int arr[3][4] = {{1,2,3,4}, {5,6,7,8}, {9,10,11,12}}; int (*p)[4] = arr; // p指向arr的第一行 printf(&quot;%d&quot;, (*p)[2]); // 输出3 printf(&quot;%d&quot;, (*(p+1))[0]); // 输出5 ``` #### 3. 与指针数组的对比 | 类型声明 | 实际类型 | 存储内容 | 内存模型 | |----------------|-------------------|-------------------|------------------| | `int *p[4]` | 指针数组 | 4个`int*`元素 | 栈区连续存储指针 | | `int (*p)[4]` | 数组指针 | 单个指针 | 指向堆/栈的数组 | #### 4. 典型应用场景 1. **二维数组传参**: ```c void print_matrix(int (*mat)[4], int rows) { for(int i=0; i&lt;rows; i++) for(int j=0; j&lt;4; j++) printf(&quot;%d &quot;, mat[i][j]); } ``` 2. **动态内存分配**: ```c int (*p)[4] = malloc(3*sizeof(int[4])); p[2][3] = 100; // 访问第三行第四列 ``` #### 5. 易错点警示 - **类型不匹配**:将普通指针赋值给数组指针会引发警告: ```c int *p1; int (*p2)[4] = &amp;p1; // 错误:类型不兼容 ``` - **维度必须明确**:C语言要求数组维度在声明时确定(C++支持模板参数化维度)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值