(pointer + n) 和 pointer[n] 有什么区别?

What is the difference between (pointer + n) and pointer[n]?

提问人:TAJ-32 提问时间:7/21/2023 最后编辑:Vlad from MoscowTAJ-32 更新时间:7/21/2023 访问量:89

问:

在此代码中,我不明白为什么要将输入字符值放入 (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?

希望对此描述得足够具体,如果不是,请告诉我。

谢谢!

c malloc 指针算术

评论

3赞 Weather Vane 7/21/2023
(ptr + i)是相同的地址,而 是它的值,也是 。所以是相同的&ptr[i]ptr[i]*(ptr + i)scanf (" %c", ptr + i);scanf (" %c", &ptr[i]);
0赞 273K 7/21/2023
(pointer + n)是或 - 这些是唯一的区别。&pointer[n]&n[pointer]pointer[n]*(pointer + n)[pointer]n
0赞 Tom Karzes 7/21/2023
a[i]只是句法糖。这意味着算子是可交换的,确实如此。所以 和 是等价的,尽管按照惯例,您应该将指针放在左侧,将偏移量放在右侧。*(a+i)[]a[i]i[a]
0赞 TAJ-32 7/21/2023
非常感谢你,这很有意义。我真的很感激!
0赞 Richard Pennington 7/21/2023
我最喜欢的是:1[“hello”] == 'e'。

答:

3赞 Vlad from Moscow 7/21/2023 #1

由于指针算术的原因,表达式具有类型并指向数组的第 i 个 elemenet。该函数需要一个指向输入数据将存储到的对象的指针。ptr + ichar *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

1赞 ikegami 7/21/2023 #2

ptr[i]根据定义,等价于 。*(ptr + i)

这意味着

&ptr[i]等价于 和 。&*( ptr + i )ptr + i

因此,区别在于代码传递的是 to 的值,而是传递 to 的地址。ptr[i]printfptr[i]scanf

我们需要传递一个指针,因为具有 的值不允许它写入 。只有传递 的地址才能做到这一点。但只需要该值来格式化和打印。它不在乎价值从何而来。scanfptr[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] );
0赞 Geetesh Paidi 7/21/2023 #3

地址处的值 (ptr+i) 或简称 (ptr+i) 与 ptr[i] 相同。您已经提到您知道 ptr+i 表示内存位置为 (指针数据类型的 i 个字节)。我认为值得一提的是,数组也是指向数组的第 0 个索引的指针。另一个主要问题是,尽管它们作为指针和数组是相同的,但一旦数组初始化为 int array[size] ,就无法重新初始化数组,但如果数组初始化为 array,则始终可以重新初始化数组: *int 数组

因此,我会说两者都是相同的,您应该根据自己的问题和方便使用它们。 我希望这会有所帮助。