int (*p)[4]等同于int *p[4]吗?

本文详细解释了C语言中int*p[4]与int(*p)[4]的区别,前者为指针数组,后者为数组指针。通过示例程序演示了如何使用数组指针遍历二维数组。

答:不等同。

int *p[4]是一个指针数组,就是数组里面放的是指针。由于[]比*优先级更高,因此p先与[4]结合,形成p[4]形式,这显然是数组形式,它有4个元素,然后再与p前面的*结合,*表示此数组是指针类型的,每个数组元素(也就是一个指针变量)都可以指向一个整形变量。

*p[4]是指针数组,他是数组。数组里面放的是指针,简单的说定义了4个指针,分别是*p[0] *p[1] *p[2] *p[3],相当于将这四个指针打包到这个数组中

(*p)[4]是数组指针,他是指针并且是一个指向一维数组的指针。因为以行为单位,又称行指针。 通俗点讲,后面的[4]说明他的每行有4个元素,[0]代表第一列的下标,[1]代表第二列的下标,一次类推。(*p)的意思是指针p指向第一行,*(p+1)即指向第二行,同理一次类推。那么*(p+2)[3]的意思即是指一维数组第二行第四列的元素

实例:
 void main()
{
	int a[3][4] ={1,3,5,7,9,11,13,15,17,19,21,23};
	int (*p)[4],i,j;
	p = a;
	scanf("i = %d,j = %d",&i,&j);
	printf("%d",*(*(p+i)+j));
	
}
输入i=1,j=2
结果:13

分析
int (*p)[4]表示p是一个指针变量,它指向包含4个整形元素的一维数组。注意*p两侧的()不可缺少。
对照下列:
(1)int a[4];(a有4个元素,每个元素为整形)‘
(2)int (*p)[4](p所指的对象是有4个整形元素的数组,即p是一维数组的指针,应该记住此时p只能指向一个包含4个元素的一维数组,p的值是该一维数组的起始地址。)
p->| (*p)[0] | (*p)[1] | (*p)[2] | (*p)[3] | 
p->| 1 | 3 | 5 | 7 |
p+1->| 9 | 11 | 13 | 15 |
p+2->| 17 | 19 | 21 | 23 |
其中p+i是二维数组的a的i行的起始地址(由于p是指一维数组的指针变量,因此p加1,就指向下一行),那么*(p+2)+3是什么呢?由于p=a,因此*(p+2)就是a[2],*(p+2)+3就是a[2]+3,而a[2]的值是数组a中第3行第0列a[2][0]那么*(*(p+2)+3)就是a[2][3]
另外*(p+2)是a数组第3行的首地址,而p+2是a数组第3行的起始地址,二者值相同,那*(p+2)+3能否写成(p+2)+3呢?显然不成,不能做简单的数值替换。(p+2)+3就成了p+5了,是a数组第6行的起始地址。
要注意"*(p+2)+3"括号中的2以一维数组的长度为单位的,即p每加1,地址就增加8个字节(4*2个字节),而"*(p+2)+3"括号外面的3,不是以p所指向的一维数组位长度为单位的。3是以元素的长度为单位的,加3就是加(3x2)个字节。虽然p+2和*(p+2)具有相同的值,但是它们所指向的对象的长度是不同的。

-------------------------------------------------------------------------------------------------
这是一个数组指针,指向对象是这个数组; 
示例:
static int m[3][4]={0,1,2,3,4,5,6,7,8,9,10,11};/* 定义二维数组m并初始化*/
    int (*p)[4];//数组指针  p是指针,指向一维数组,每个一维数组有4个int元素
    int i,j;
    p=m;    //p是指针,可以直接指向二维数组
    printf("--数组指针输出元素--\n");
    for(i=0;i<3;i++)/*输出二维数组中各个元素的数值*/
    {
        for(j=0;j<4;j++)
        {
            printf("%3d ",*(*(p+i)+j));
        }
        printf("\n");
    } 
<think>首先,用户的问题是:判断代码 `int *p=0;*p=100;` 是否正确。我需要根据提供的引用和自己的知识来回答。 回顾系统级指令: - 所有行内数学表达式用 `$...$`。 - 独立公式用 `$$...$$`。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 引用的段落末尾添加引用标识,例如 `[^1]`。 - 回答结构清晰,帮助用户逐步解决问题,保证真实可靠。 用户提供了几个引用: - 引用[1]:关于指针的关系运算,示例代码中使用了指针比较。 - 引用[2]:关于无符号整数和整数的比较,以及条件运算符。 - 引用[3]:关于const指针的问题,演示了如何通过指针修改常量导致问题。 - 引用[4]:关于路径规划算法的实现细节,似乎不直接相关。 用户的问题是关于代码 `int *p=0;*p=100;` 的正确性。关键点是: - `int *p=0;`:声明一个指针p并初始化为0(NULL)。 - `*p=100;`:解引用p并赋值100。 这涉及到指针操作,特别是空指针解引用。 从引用[3]中,有一个类似的问题:它讨论了通过指针修改常量值,导致未定义行为。在引用[3]的代码中: ```c const int x = 1; int* p; const int** q = &p; *q = &x; *p = 2; // 修改常量x的值 ``` 这会导致未定义行为,因为x是常量。 在用户的问题中,`p` 被初始化为0,这等同于NULL。解引用NULL指针在C和C++中是未定义行为,因为它试图访问无效的内存地址。 因此,代码 `int *p=0;*p=100;` 是不正确的,因为它会导致运行时错误(如段错误)。 现在,构建我的回答: 1. **结构清晰**:逐步解释代码,指出问题。 2. **使用中文**。 3. **添加引用**:引用相关的引用[3],因为它涉及指针解引用的安全问题。 4. **生成相关问题**:在末尾添加相关问题。 5. **确保真实可靠**:基于C/C++标准,解引用NULL指针是未定义行为。 回答大纲: - 解释代码:第一行声明并初始化指针p为NULL。 - 第二行解引用p并赋值,但由于p是NULL,会导致未定义行为。 - 指出这在编译时可能通过,但在运行时崩溃。 - 引用引用[3]来支持指针操作的危险性。 - 建议避免这种代码。 相关问题: - 如何安全地初始化指针? - 什么是未定义行为在C/C++中? - 如何检测空指针解引用? 最后,应用指令: - 行内表达式如变量名,用 `$...$`,例如 `$p$`。 - 独立公式如果需要,但这里可能不需要。 - 引用标识:在引用的地方添加 `[^3]`。 完整的回答: - 先回答问题:代码不正确。 - 解释原因。 - 添加相关问题。 </think> ### 判断代码 `int *p=0;*p=100;` 的正确性 这段代码 `int *p=0;*p=100;` **不正确**,会导致严重的运行时错误。下面我将逐步解释原因,并基于C/C++语言规范进行分析。 #### 1. **代码解析** - `int *p=0;`: 声明一个整型指针 `$p$` 并将其初始化为0。在C/C++中,0表示空指针(NULL),即 `$p$` 不指向任何有效的内存地址。 - `*p=100;`: 尝试解引用指针 `$p$`(即访问 `$p$` 指向的内存位置)并赋值100。但由于 `$p$` 是空指针,这里涉及访问无效内存。 #### 2. **错误原因:未定义行为** - 解引用空指针(如 `$*p$`)在C/C++标准中属于**未定义行为**(Undefined Behavior, UB)。这意味着: - 编译器可能不会报错(编译时可能通过),但程序运行时必然崩溃(如触发段错误)。 - 实际行为不可预测:可能表现为程序终止、数据损坏或安全漏洞。 - 在您的引用[^3]中,类似地演示了通过指针修改常量导致的未定义行为(例如修改 `const int` 的值)。该案例强调:“非常量指针操作常量对象可能破坏数据完整性”,而本代码的 `$*p=100;$` 同样因访问非法内存而引发类似风险。 #### 3. **具体风险示例** - 运行此代码时,操作系统通常会阻止对地址0的访问,导致**段错误**(Segmentation Fault)。例如: ```c int main() { int *p = 0; // p 是空指针 *p = 100; // 运行时崩溃! return 0; } ``` - 输出可能为:`Segmentation fault (core dumped)`。 #### 4. **修正建议** - **安全初始化指针**:始终为指针分配有效内存地址后再解引用。例如: ```c int main() { int value; // 分配有效内存 int *p = &value; // p 指向 value *p = 100; // 正确:修改 value 的值 return 0; } ``` - **检查空指针**:在使用指针前添加判空逻辑: ```c if (p != NULL) { *p = 100; } ``` #### 5. **总结** - 代码 `int *p=0;*p=100;` 错误的核心是**解引用空指针**,违反了内存安全原则。虽然编译可能成功,但运行时会崩溃,属于严重编程错误。务必确保指针指向有效内存区域后再进行操作。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

anssummer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值