在我的C程序书中,我遇到了关于(*p)[num2]的问题 有一个名为a[num1][num2]的二维数组和一个(*p)[num2] 接下来,在声明中

for(p=&a[0];p<&a[num1];p++)
(*p)[i]=0;

该语句将使2维数组的i列赋值为0 但我不明白为什么(*p)[num2]指的是a‘S行,我认为创造*pp=&a[num1]也可以做到这一点. 还有,为什么p++指向下一行,而不是a[num][i]后面的下一个值

为什么?我明白了*p[3](*p)[3]之间的区别 我认为*p可以指向一个数组(第一个地址),为什么使用(*p)[num]来指向array.

推荐答案

让我们从引用C标准中有关数组和隐式转换(6.3.2.1 L值、数组和函数指示符)的有用引语开始.

3除非它是sizeof运算符的操作数,或者是一元&; 运算符,或者是用于初始化数组的字符串文字,an expression that has type "array of type" is converted to an expression with type "pointer to type" that points to the initial element of the array object,而不是左值.如果数组对象已注册 存储类,则行为未定义.

举个例子,如果你有一个这样的数组

int a[num1][num2];

然后在引号中提到的极少数例外的表达式中使用,它被隐式转换为指向其初始元素的指针.

二维数组a的元素又是类型int[num2]的array.指向数组的元素类型的指针具有类型int ( * )[num2].您可以通过以下方式声明相应的指针

int ( *p )[num2] = a;

这是相同的

int ( *p )[num2] = &a[0];

现在,指针p指向二维数组a的第一行.在使用前缀增量运算符++p或后缀增量运算符p++递增它之后,它将指向数组a的类型int[num2]的下一个(第二)元素(行).取消对指针的引用,如*p,您将获得指针指向的int[num2]类型的一维数组(ROW).要将下标运算符( *p )[i]应用于结果表达式,您将获得数组a的当前行的i-th元素.

另一方面,如果你有

int ( *p )[num2] = a;

则表达式p + num1将指向数组a的最后一个元素(类型为int[num2]的一维数组)之后的存储器.表达式p + num1等同于表达式a + num1(由于将数组a隐式转换为指向其初始元素的指针),该表达式a + num1又等同于表达式&a[num1].根据最后一个表达式,用C标准编写(6.5.3.2地址和间接运算符)

3一元&;运算符得出其操作数的地址.如果 操作数的类型为"type",结果的类型为"指向类型的指针".如果 操作数是一元*运算符的结果,既不是该运算符也不是 对&;运算符进行求值,结果就好像两者都被省略了, 只是运算符上的约束仍然适用,并且 结果不是左值.如果不是Similarly, if the operand is the result of a [] operator, neither the & operator nor the unary * that is implied by the [] is evaluated and the result is as if the & operator were removed and the [] operator were changed to a+ operator., 结果是一个指针,指向由其 运算数.

因此,从引号中可以看出,表达式&a[num1]等同于表达式a + num1.

因此,这是for循环

for ( p = &a[0]; p < &a[num1]; p++ )
    ( *p )[i] = 0;

可以重写为

for ( p = a; p < a + num1; p++ )
    ( *p )[i] = 0;

至于下标运算符则(C标准,6.5.2.1数组下标):

2后缀表达式后跟方括号中的表达式[] 是数组对象的元素的下标指定.这个 下标运算符[]的定义是:E1[E2]相同 至(*((E1)+(E2).由于适用于 二进制+运算符,如果e1是数组对象(等效于指向 数组对象的初始元素),并且E2是整数,e1[e2] 指定E1的第2个元素(从零开始计数).

因此,For循环体中的以下表达式语句

( *p )[i] = 0;

也可以重写为

*( *( p + 0 ) + i ) = 0;

或者喜欢

*( *p + i ) = 0;

C++相关问答推荐

有什么方法可以检测SunOS上的SparcWorks吗?

什么C代码将确定打开的套接字正在使用的网络适配器?

当打印字符串时,为什么在c中没有使用常量限定符时我会收到警告?

使用额外的公共参数自定义printf

#If指令中未定义宏?

用C语言计算文本文件中的整数个数

关于scanf()和空格的问题

如何在双向表中实现线程安全,每个条目仅使用4位,同时避免任何全局锁?

这段代码用于在C中以相反的顺序打印数组,但它不起作用

从C中的函数返回静态字符串是不是一种糟糕的做法?

将非连续物理内存映射到用户空间

c程序,让用户输入两类数字,并给出输出用户输入多少个数字

Makefile无法将代码刷新到ATmega328p

我正在使用c学习数据 struct ,在学习堆栈时,我试图将中缀转换为后缀,并编写了这段代码.代码未给出输出

使用mmap为N整数分配内存

在我的函数中实现va_arg的问题

通过char*访问指针的对象表示是未定义的行为吗?

即使客户端不发送数据,也会发生UNIX套接字读取

变量的指针右对齐,函数的指针左对齐

C 中从 Unix 纪元时间转换的损坏