Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 理解和操作指向整数数组的指针_C_Arrays_Pointers_Array Pointer - Fatal编程技术网

C 理解和操作指向整数数组的指针

C 理解和操作指向整数数组的指针,c,arrays,pointers,array-pointer,C,Arrays,Pointers,Array Pointer,我在以下代码中遇到问题: int a[] = {1, 2, 3, 4}; fprintf(stdout, "a : %lu\n" "*a : %d\n" "&a : %ld\n" "**(&a) : %d\n", (unsigned long int)a, *a,

我在以下代码中遇到问题:

int a[] = {1, 2, 3, 4};
  
fprintf(stdout,
        "a      : %lu\n"
        "*a     : %d\n"
        "&a     : %ld\n"
        "**(&a) : %d\n",
        (unsigned long int)a,
        *a,
        (unsigned long int)&a,
        **(&a)
);
输出:

a      : 140726063647232
*a     : 1
&a     : 140726063647232
**(&a) : 1
我知道&a是指向一维数组的指针。And&a的类型为int*[4]。 我不明白**&a:1是怎么来的。

&a是指向数组的指针*p获取指针指向的对象,因此*&a获取数组a

作为指针处理的数组退化为指向其第一个元素的指针,因此*a为1

因为*&a只是a,***&a与*a相同,后者是1。

&a是指向数组的指针*p获取指针指向的对象,因此*&a获取数组a

作为指针处理的数组退化为指向其第一个元素的指针,因此*a为1


由于*&a只是a,***&a与*a相同,后者为1。

另一种查看方法是通过每次地址或取消引用操作后的结果类型。数组访问的一个基本规则是数组指针转换。这适用于任何阵列的访问,但须遵守所列的4个例外情况[C18标准中的3-_Alignofis不再列出]

关键是要理解数组在访问时会被转换为指向第一个元素的指针,该元素会受到有限的异常影响,这在这里并不相关。如果采用数组的地址,则地址与第一个元素的地址相同,但指针的类型完全不同

取消引用a时,将获得第一个元素:

    *a   - int
**(&a)   - int
为什么?*a是偏移量为0的完全去费伦斯运算的缩写,例如.*a+0,相当于索引表示法中的[0]

当您取消对数组int[4]的引用时,您将返回数组:

 *(&a)   - int[4] -> converted to pointer to first element.
然后,通过的操作,将其转换为指向第一个元素的指针。再次取消引用将获得第一个元素:

    *a   - int
**(&a)   - int

现在值得学习,因为它将在以后为您省去很多困惑。

另一种方法是通过每个地址或取消引用操作后的结果类型来查看它。数组访问的一个基本规则是数组指针转换。这适用于任何阵列的访问,但须遵守所列的4个例外情况[C18标准中的3-_Alignofis不再列出]

关键是要理解数组在访问时会被转换为指向第一个元素的指针,该元素会受到有限的异常影响,这在这里并不相关。如果采用数组的地址,则地址与第一个元素的地址相同,但指针的类型完全不同

取消引用a时,将获得第一个元素:

    *a   - int
**(&a)   - int
为什么?*a是偏移量为0的完全去费伦斯运算的缩写,例如.*a+0,相当于索引表示法中的[0]

当您取消对数组int[4]的引用时,您将返回数组:

 *(&a)   - int[4] -> converted to pointer to first element.
然后,通过的操作,将其转换为指向第一个元素的指针。再次取消引用将获得第一个元素:

    *a   - int
**(&a)   - int
这是值得现在学习的,因为它将节省你很多困惑以后

如果要打印地址,应使用printf或fprintf函数的%p转换说明符。 另一方面,在使用上述相同函数打印整数数据类型时,应使用%d转换说明符。然后您可以省略所有向上转换为无符号长整型的数据类型。 在您的情况下,c数组衰减到相同数据类型的指针并非在所有情况下,数组都可以衰减到指针。在您的打印中,您使用了这个事实,例如,当取消引用数组*a时。c语言中的这一事实使我们能够写出以下语句: int*a_ptr=a;和int*ptr=&a[0];。现在a_ptr和ptr相等!指向内存中的同一地址。 打印a类似于打印a_ptr值,也类似于打印ptr值。以打印&a[0]结尾。 打印*a类似于打印*a_ptr和打印*ptr,因为ptr=&a[0];然后,*ptr==*&a[0]==a[0],所以简单地说就是a[0],它是1。 priniting&a。现在什么是&a?它是指向整数数组的指针!更精确地说,它是一个指向4个整数的数组的指针,它是int*[4],所以当打印a的地址时,它就像打印*int*[4]的解引用一样,它是简单数组a的地址。请注意,数据类型是不同的!a和a! 打印**&a与**int*[4]与*a相同,后者与*a+0相同,后者与*ptr相同,后者是:a[0]是1。 将代码段修复为:

int a[] = {1, 2, 3, 4};

fprintf(stdout,    /*you can use printf instead of fprintf(srdout,)*/
    "a      : %p\n"
    "*a     : %d\n"
    "&a     : %p\n"
    "**(&a) : %d\n",
       a,
      *a,
      &a,
   **(&a)
);
如果要打印地址,应使用printf或fprintf函数的%p转换说明符。 另一方面,在使用上述相同函数打印整数数据类型时,应使用%d转换说明符。然后您可以省略所有向上转换为无符号长整型的数据类型。 在您的情况下,c数组衰减到相同数据类型的指针并非在所有情况下,数组都可以衰减到指针。在您的打印中,您使用了这个事实,例如,当取消引用数组*a时。c语言中的这一事实使我们能够写出以下语句: int*a_ptr=a;和int*ptr=&a[0];。现在a_ptr和ptr相等!指向同一个地址,我 n内存。 打印a类似于打印a_ptr值,也类似于打印ptr值。以打印&a[0]结尾。 打印*a类似于打印*a_ptr和打印*ptr,因为ptr=&a[0];然后,*ptr==*&a[0]==a[0],所以简单地说就是a[0],它是1。 priniting&a。现在什么是&a?它是指向整数数组的指针!更精确地说,它是一个指向4个整数的数组的指针,它是int*[4],所以当打印a的地址时,它就像打印*int*[4]的解引用一样,它是简单数组a的地址。请注意,数据类型是不同的!a和a! 打印**&a与**int*[4]与*a相同,后者与*a+0相同,后者与*ptr相同,后者是:a[0]是1。 将代码段修复为:

int a[] = {1, 2, 3, 4};

fprintf(stdout,    /*you can use printf instead of fprintf(srdout,)*/
    "a      : %p\n"
    "*a     : %d\n"
    "&a     : %p\n"
    "**(&a) : %d\n",
       a,
      *a,
      &a,
   **(&a)
);

您应该使用%p作为指针,而不是%lu。如果您对编程语言比较陌生:在C中,数组也是指针。对于基本的语言概念,打字,其他一些语言可能会更好。至少在教育学上。**&a 100%等同于*a,仅此而已。这只是混淆——故意写不好的代码。@Lundin,混淆是故意的,目的是教人去引用和引用。@AnshumanKumar那么为什么它不是写为**&a或**&a呢?前者是最干净的,如果你希望学生不掌握优先级/联想性,后者是有意义的。不过介于两者之间?您应该使用%p作为指针,而不是%lu。如果您对编程语言比较陌生:在C中,数组也是指针。对于基本的语言概念,打字,其他一些语言可能会更好。至少在教育学上。**&a 100%等同于*a,仅此而已。这只是混淆——故意写不好的代码。@Lundin,混淆是故意的,目的是教人去引用和引用。@AnshumanKumar那么为什么它不是写为**&a或**&a呢?前者是最干净的,如果你希望学生不掌握优先级/联想性,后者是有意义的。介于两者之间?