问题 给定`int num [7]`,`num`,`&num [0]`,`&num`如何不同?


我读了一本关于阵列的C书 num[7] 期限 num 相当于 &num[0]。这个概念对我来说很好,但是当我写下这个程序时,我再次感到困惑。

#include<stdio.h>
#include<conio.h>
int main()
{
    int num[]={21,22,23,24,25,26,27};
    int *x,*y,*z;
    x=&num;
    y=num;
    z=&num[0];
    printf("%d   %d   %d\n",sizeof(x),sizeof(y),sizeof(z));
    printf("%d  %d  %d\n",sizeof(&num),sizeof(num),sizeof(&num[0]));
    printf("%d   %d   %d",*(&num),*(num),*(&num[0]));
    getch();
    return 0;  
}

输出是:

      4    4    4
      4    28   4
      2293536   21   21

如果 num 是完全相同的 &num[0] 那为什么它们的大小有所不同?什么是第三类术语 &num?我知道它显示了垃圾值,但这种类型的术语是否有意义? z=&num[0] 我已经明白了。编译器显示分配警告 x=&num, 但对于 y=num; 编译器没有任何问题。如果 num 有大小 28 那为什么它被分配给一个整数指针 y 没有类型转换?

然后我用这种方式尝试二维数组:

#include<stdio.h>
#include<conio.h>
int main ()
{
    int s[4][2]={{1234,56},{1235,57},{1236,58},{1237,59}};
    int i
    printf ("\n%d %d %d %d %d",sizeof(s[i]),sizeof(&s[i]),sizeof(s),
        sizeof(s[0][0]),sizeof(&s));
    getch();
    return 0;
}

现在输出是

8  4  32  4   4

这里 sizeof(s[i]) 是 8。因为 s[i] 是一个一维数组,它有两个元素,所以它很好。但我对这些条款没有任何线索 &s[i] 和 &s 意思。我再次能够看到这一点 s 与...不完全相同 s[0][0] 。我使用Dev C ++ 4.9.9.2版本来运行所有程序。我希望在这三种术语中清楚明白。


2276
2017-08-27 20:28


起源

阅读C FAQ,其中包含专门针对此问题的整个部分: c-faq.com/aryptr/index.html - AnT
@good问题为初学者!伙伴 - niko


答案:


哇,一下子就有很多问题:P

首先,我将尝试向您解释此输出:

  4    4    4
  4    28   4
  2293536   21   21

sizeof() 是c中的一元运算符。编译代码时,它会被整数替换,而不是在运行时。因此,编译器会将您的printfs更改为:

 printf("%d   %d   %d\n", 4, 4, 4);
 printf("%d  %d  %d\n", 4, 28, 4);
 printf("%d   %d   %d",*(&num),*(num),*(&num[0]));

在编译的早期阶段。

编译器非常友好,可以在您编写时为您提供整个数组的大小 sizeof(num)。这就是定义sizeof如何在数组上工作。除了sizeof(&num)之外,所有其他元素都给出了(int *)的大小,它给出了(int **)的大小(int **与int *的大小相同)。

  • &num是指向数组的指针的内存位置
  • num和#num [0]是数组中第一个int的内存位置

对于你的第二个问题;

printf("\n%d %d %d %d %d",sizeof(s[i]),sizeof(&s[i]),sizeof(s),sizeof(s[0][0]),sizeof(&s));

sizeof(s[i]) - size of an array (int[2]) == 8
sizeof(&s[i]) - size of a pointer to an int array sizeof(int **) == 4
sizeof(s) - size of a 2D array containing 8 ints == sizeof(int[8]) == 32
sizeof(s[0][0]) - size of an int === 4
sizeof(&s) - size of a pointer to an array == 4

2
2017-08-27 20:46





这里有好问题。希望我们都能为您解释这些问题。

特定

int num[]={21,22,23,24,25,26,27};

然后

  • num 有类型 int[] 因为它是一个声明的整数数组,其内存被分配到位。请注意它确实如此  有类型 int*如果你使用malloced它就是这种情况。
  • sizeof(num) 是28因为 num 是一个7个整数的数组,在你的机器上是4个字节大小。如果整数是8个字节,则值为56;如果它们具有2个字节,则值为14,但每个整数最多4个字节。
  • &num[0] 是一个类型的指针 int*,谁的  是第一个元素的地址 num
  • 的大小 x 和朋友是4因为它们被声明为指针,在你的机器上,在你的C编译器下,指针被分配为4个字节。

要记住的是,当在某些上下文中使用数组时,比如作为参数传递,它将被转换为 int*。这就是为什么你可以说 *num 得到21.棘手,但就是这样。这就是人们通常可以互换的原因 num 和 &num[0] 但你真的应该记住这个区别,因为正如你所注意到的那样 sizeof 价值观不同。

转换是原因 y = num 说得通。 y 有类型 int* 在C中你可以自动转换 int[] 至 int*。你做不到 x = &num 因为的类型 &num 是“指向int数组的指针”。你不能将它分配给 int* (指向int的指针)。

如果是

int s [4] [2] = {{1234,56},{1235,57},{1236,58},{1237,59}};

我们有类型 s 如 int[][],类型 &s 如 pointer to int[][] 和的类型 &s[i] 作为指针 int[] (因为 s[i] 是一个int数组)。由于C允许您为指针分配/传递数组的方式,您可以使用与第一个示例中相同类型的游戏。

你会注意到的 s&s[0] 和 &s[0][0] 所有都指向相同的内存位置,但是,正如您所注意到的那样 sizeof 价值观会有所不同。


5
2017-08-27 20:39



@pst,对,我做了太多的假设。它包含7个四字节整数。是的,OP可以在具有不同大小的整数的机器上。 - Ray Toal
更好,一个+1:p


你的矛盾是有效的。它是  那个案子 num 相当于 &num[0]。那简直是假的。数组是与指针不同的类型 num 指的是具有该类型的对象 int[7]不是 int*。这就是为什么尺寸不同,例如,因为一个是七个整数的连续集合。

请注意,如果需要, num 可以转换为 int*,有价值 &num[0]。当然,转换与等价不同。你会发现数组和指针之间的混淆奇怪地突出,因为人们不断重复数组指针的虚假。他们不是。


3
2017-08-27 20:34





现在我的问题是,如果num与#num [0]相同,那么为什么有一个   有大小差异?

num 是一个数组。 sizeof 对于数组而言,它有时会出现令人惊讶的行为,如果你将它传递给一个实际的数组,它会告诉你整个数组的存储大小,但它只告诉你如果你传递了一个数组中元素的指针的大小这样一个元素。这可能会导致混淆,因为数组名称会降级为函数调用中的指针。

所以答案是这样的 num 与...不完全相同 &num[0]  - 后者是第一个元素的地址 num,删除有关阵列总大小的任何信息。这两件事在许多情况下都是可以互换的,例如调用实际函数,但在调用时则不然 sizeof (这不是函数,而是由编译器处理的特殊关键字)。


3
2017-08-27 20:35