关于int *p[n]和int (*p)[n]的超详细讲解

本文详细解析了C语言中各种指针及数组的声明方式,包括int *p[n]与int (*p)[n]的区别,以及函数指针的定义与使用方法。通过深入浅出的解释,帮助读者理解指针的复杂概念。

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

在编程中,会遇到这样的情况:
int *p[n];
int (*p)[n];
还有一种情况是声明函数:
int *p();
int (*p)();
这些分别表示什么意思呢?

表面上看这些问题,好像是指针,但是,如何来正确判断这几个定义,需要我们首先有运算符优先级的概念。

在c语言中,[]和()的优先级比星号(星号的名字叫做“指针运算符”)要高,所以,在这几个声明中,先看[]和()。
同时,这两个括号的运算符的结合顺序,是从左到右的。因此,int *p[n],实际上相当与int *(p[n]),也就是(int *)(p[n])。

让我们来逐步分析:
(int *)(p[n])首先是一个数组(比如,把int *换为int,就是“元素是整形数据的数组”。那么,换为int*,就是“元素是指向整形数据的指针的数组”)。

再看另一个:
int (*p)[n]改变了自然的运算符的优先级,相当于(int)((*p)[n])。一有指针就头疼,我们把指针先替换掉,就是int a[n],是一个n维数组,数组首地址(也就是数组名)是a。
那么,int (*p)[n]也是一个n维数组,但是这个数组的首地址是*p,也就是说,p指向的内容,是一个数组的首地址。
那么,p就是指向一个数组的指针,这个数组中的元素都是int。实际上,p相当于是一个二维指针。

同样的道理,可以分析 int *p();和int (*p)();

注意,这里我们对于星号赋予了不同的含义。阐述如下:
int a;
int *p=&a;//定义指向a的指针p
*p = 10;

这里,第二行中的星号表示“定义了一个指向int型数据的指针,为什么呢?因为实际上,* 相当于 (int *),定义了一个指向int型数据的指针。
第三行的星号,表示p所指向的数据,因为星号前面并没有诸如int void char等表示类型的东西。

换句话说,如果星号前面有表示类型的int,void等数据,我们认为,这里的星号的意义,是“定义了一个指针”
如果星号前面没有表示类型的东西,那么我们认为,这里的星号的意义,是”该指针所指向的数据“。

那么,让我们回头看看int *p[n]和int (*p)[n]。
由于我们刚刚把优先级分析过,那么前者相当于(int *)(p[n]),后者相当于 int ((*p)[n])
根据刚才我们的关于星号的结论,前者表示定义了一个长度为n的数组(p[n]),每个元素都是指向int数据的指针(int *)。
后者表示,定义了一个int a[n]。这里大家都明白,然后把a换成*p,于是意思就是,p是一个指针,其指向的内容(也就是*p)是一个数组的首地址(就是a)

int *(*p)[4];(*P)表示p是一个指针,然后与右边的[]结合,表示P是指向一个有四个元素的数组,
int *表示返回指向整形的指针,所以int *(*p)[4];表示p指向一个有含有四个指向整形的指针元素的数组

int (*p)(int)是函数指针,如:
int func(int x); /* 声明一个函数 */
int (*f) (int x); /* 声明一个函数指针 */
f=func; /* 将func函数的首地址赋给指针f */

int* p(int x);是一个返回值为int型指针的函数的声明
可以用typedef 定义函数指针类型,用于定义函数指针;

int *p(int),不就是个函数声明
int*是返回值类型,p是函数名,(int)是参数类型

p是函数,函数参数是一个int整型,返回值是指向一个整型的指针(int *)

设有语句int(*p)();则p是一个(     )
	     A.指向一维整型数组的指针变量 
	     B.指针函数,该函数的返回值为指向整型变量的指针 
	     C.指向函数的指针变量,该函数的返回值为整型 
	     D.数组指针,它的每个元素都是一个可以指向整型变量的指针变量

p是指向函数的指针变量,这题选C。
具体用法:
         你可以定义一个 int func()的函数;可把函数func()赋给p作为p的值,即把func()的入口地址赋给p,以后就可以用p来调用该函数,实际上p和func都指向同一个入口地址,不同就是p是一个指针变量,不像函数名称那样是死的,它可以指向任何函数,就看你想怎么做了。在程序中把哪个函数的地址赋给它,它就指向哪个函数。
<think>好的,我需要回答用户关于C++中newdelete运算符的正确使用方法的示例解析。首先,我应该回顾用户提供的引用内容,确保回答准确。根据引用[1]、[2][3],new用于动态分配内存,delete用于释放内存,需要注意匹配使用,避免内存泄漏悬空指针。 用户需要具体的示例,所以我应该分步骤讲解基本用法、数组处理、类对象以及常见错误。首先,单个对象的分配释放,比如int* p = new int;然后delete p;。对于数组,要用new[]delete[],如int* arr = new int[10];然后delete[] arr;。对于类对象,构造函数析构函数会被自动调用,这需要示例说明。 还要注意常见错误,比如忘记释放内存导致泄漏,或者错误使用delete形式(比如用delete而不是delete[]),这会导致未定义行为。此外,悬空指针的问题,释放后应将指针置为nullptr。 需要确保所有代码示例语法正确,并符合C++标准。同时,要提醒用户使用智能指针来避免手动管理内存的风险。可能还需要对比malloc/freenew/delete的区别,但用户的问题主要关注newdelete,所以可能不需要深入讨论。 现在组织内容结构,先介绍基本用法,再分情况讨论,接着给出正确示例错误示例,最后总结注意事项。确保每个部分都有代码示例,并引用提供的参考文献来支持观点。例如,在讨论数组时引用[2],在讨论析构函数时引用[3]。 还要检查是否有遗漏点,比如异常安全,但用户可能只需要基础的正确用法,所以暂不深入。确保回答清晰,步骤明确,帮助用户理解如何正确使用newdelete。</think>### C++中newdelete运算符的正确使用方法解析 #### 1. 基本操作原则 - **new**:动态分配单个对象或数组内存,触发构造函数(若为类对象) - **delete**:释放通过new分配的内存,触发析构函数(若为类对象) - **必须严格匹配**:`new`对应`delete`,`new[]`对应`delete[]`[^1][^2] #### 2. 基础使用示例 **单个对象分配:** ```cpp int* p = new int; // 分配未初始化的int内存 int* p2 = new int(42); // 分配并初始化为42 delete p; // 正确释放 delete p2; // 正确释放 ``` **数组分配:** ```cpp int* arr = new int[10]; // 分配10个int的数组 delete[] arr; // 必须使用delete[] ``` #### 3. 类对象管理 ```cpp class MyClass { public: MyClass() { std::cout << "构造函数\n"; } ~MyClass() { std::cout << "析构函数\n"; } }; MyClass* obj = new MyClass; // 触发构造函数 delete obj; // 触发析构函数 ``` *输出结果:* ``` 构造函数 析构函数 ``` #### 4. 多维数组处理 ```cpp // 二维数组分配 int** matrix = new int*[5]; for(int i=0; i<5; ++i) { matrix[i] = new int[10]; } // 释放内存 for(int i=0; i<5; ++i) { delete[] matrix[i]; } delete[] matrix; ``` #### 5. 常见错误示例 **错误1:类型不匹配** ```cpp int* arr = new int[10]; delete arr; // 错误!应使用delete[] ``` **错误2:重复释放** ```cpp int* p = new int; delete p; delete p; // 运行时错误:重复释放已释放内存 ``` **错误3:内存泄漏** ```cpp void func() { int* p = new int[100]; // 忘记delete[] p; } ``` #### 6. 最佳实践建议 1. **优先使用智能指针**:如`std::unique_ptr`,`std::shared_ptr` 2. **释放后置空指针**: ```cpp delete ptr; ptr = nullptr; // 防止悬空指针 ``` 3. **异常安全处理**:使用`try-catch`块确保异常时内存释放[^3] 4. **RAII原则**:通过构造函数分配、析构函数释放资源
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值