提问人:TAJ-32 提问时间:7/21/2023 最后编辑:Vlad from MoscowTAJ-32 更新时间:7/21/2023 访问量:89
(pointer + n) 和 pointer[n] 有什么区别?
What is the difference between (pointer + n) and pointer[n]?
问:
在此代码中,我不明白为什么要将输入字符值放入 (ptr + i) 中,然后我们打印出 ptr[i]。我知道它们是不同的,因为我在第一个 for 循环中打印出值,但我不明白它们之间的区别是什么,以及为什么我们使用一个来接受带有 scanf 的输入,而使用另一个来输出。
#include<stdio.h>
#include<stdlib.h>
int main ()
{
int n, i;
char *ptr;
printf ("Enter number of characters to store: ");
scanf ("%d", &n);
ptr = (char *) malloc (n * sizeof (char));
printf("POINTER %p\n", ptr);
for (i = 0; i < n; i++)
{
printf ("Enter ptr[%d] (%p) (%p): ", i, ptr[i], ptr + i);
/* notice the space preceding %c is
necessary to read all whitespace in the input buffer
*/
scanf (" %c", ptr + i);
}
printf ("\nPrinting elements of 1-D array: \n\n");
for (i = 0; i < n; i++)
{
printf ("%c ", ptr[i]);
}
//signal to operating system program ran fine
return 0;
}
此外,我知道根据指针数据类型的字节数执行 ptr + i = ptr + (i * numberofbytes),因此我们将每个新输入存储到具有我们使用 malloc 的字节数的内存地址中是有意义的。但是,为什么我们打印出 ptr[i] 而不是 ptr + i?
希望对此描述得足够具体,如果不是,请告诉我。
谢谢!
答:
由于指针算术的原因,表达式具有类型并指向数组的第 i 个 elemenet。该函数需要一个指向输入数据将存储到的对象的指针。ptr + i
char *
scanf
与生成表达式 所指向的对象相同的表达式。ptr[i]
*( ptr + i )
ptr + i
从 C 标准(6.5.2.1 数组下标)
2 后缀表达式后跟方括号中的表达式 [] 是数组对象元素的下标名称。这 下标运算符 [] 的定义是 E1[E2] 等同于 (*((E1)+(E2)))。由于转换规则适用于 二进制 + 运算符,如果 E1 是数组对象(等效地,指针 到数组对象的初始元素),并且 E2 是一个整数, E1[E2] 表示 E2 的第 1 个元素(从零开始计数)。
因此,表达式指向第 i 个对象。而与产生表达式本身相同的表达式。ptr + i
*( ptr + i )
ptr[i]
ptr + i
ptr[i]
根据定义,等价于 。*(ptr + i)
这意味着
&ptr[i]
等价于 和 。&*( ptr + i )
ptr + i
因此,区别在于代码传递的是 to 的值,而是传递 to 的地址。ptr[i]
printf
ptr[i]
scanf
我们需要传递一个指针,因为具有 的值不允许它写入 。只有传递 的地址才能做到这一点。但只需要该值来格式化和打印。它不在乎价值从何而来。scanf
ptr[i]
ptr[i]
ptr[i]
printf
// Passes a pointer to `ptr[i]` to `scanf`.
// `scanf` will write at the address pointed by this pointer.
scanf( " %c", ptr + i );
// Same
scanf( " %c", &ptr[i] );
// Passes the value of `ptr[i]`.
// `printf` will print a formatting of that value.
printf( "%c ", ptr[i] );
地址处的值 (ptr+i) 或简称 (ptr+i) 与 ptr[i] 相同。您已经提到您知道 ptr+i 表示内存位置为 (指针数据类型的 i 个字节)。我认为值得一提的是,数组也是指向数组的第 0 个索引的指针。另一个主要问题是,尽管它们作为指针和数组是相同的,但一旦数组初始化为 int array[size] ,就无法重新初始化数组,但如果数组初始化为 array,则始终可以重新初始化数组: *int 数组
因此,我会说两者都是相同的,您应该根据自己的问题和方便使用它们。 我希望这会有所帮助。
评论
(ptr + i)
是相同的地址,而 是它的值,也是 。所以是相同的&ptr[i]
ptr[i]
*(ptr + i)
scanf (" %c", ptr + i);
scanf (" %c", &ptr[i]);
(pointer + n)
是或 - 这些是唯一的区别。&pointer[n]
&n[pointer]
pointer[n]
*(pointer + n)
[pointer]n
a[i]
只是句法糖。这意味着算子是可交换的,确实如此。所以 和 是等价的,尽管按照惯例,您应该将指针放在左侧,将偏移量放在右侧。*(a+i)
[]
a[i]
i[a]