C语言 给定'int num[7]','num'、'&num[0]'、'&num'有何不同?

k4aesqcs  于 2022-12-17  发布在  其他
关注(0)|答案(4)|浏览(214)

我在一本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]是一个1-D数组,它有两个元素,所以没问题。但是我不知道&s[i]&s是什么意思。我再次看到ss[0][0]是不一样的。我使用了Dev C++ 4.9.9.2版本来运行所有的项目。我想在这三个方面讲清楚。

8nuwlpux

8nuwlpux1#

问得好。希望我们都能为你解释这些问题。
给定

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

然后

  • num具有类型int[],因为它是一个声明的整数数组,其内存已分配到位。请注意,它 * 不 * 具有类型int*,如果您对它进行了malloced,则会出现这种情况。
  • sizeof(num)是28,因为num是7个int的数组,在您的机器上,其大小为4字节。如果int为8字节,则值为56;如果int为2字节,则值为14,但最常见的是每个整数4字节。
  • &num[0]int*类型的指针,其 valuenum的第一个元素的地址。
  • x和friends的大小是4,因为它们被声明为指针,而在您的计算机上,在您的C编译器下,指针是以4个字节分配的。

需要记住的是,当数组在某些上下文中使用时,比如作为参数传递时,它会被转换为int*。这就是为什么你可以说*num而得到21。这很棘手,但事实就是这样。这就是为什么人们通常可以互换num&num[0],但你真的应该记住它们的区别。因为正如您所注意到的,sizeof值不同。
y = num有意义的原因就在于这种转换。yint*类型,在C语言中,你可以得到从int[]int*的自动转换。你不能做x = &num,因为&num的类型是“指向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的值将有所不同。

3okqufwl

3okqufwl2#

你的矛盾是有道理的。num等价于&num[0]而不是的情况。这完全是假的。数组是一种不同于指针的类型,num引用的是int[7]类型的对象,而不是int*类型的对象。这就是大小不同的原因,例如,因为一是七个整数的连续集合。
注意,如果需要的话,num可以被转换成int*,值为&num[0]。当然,转换和等价是不一样的。你会发现数组和指针之间的混淆非常突出,因为人们一直在重复数组是指针的错误。其实它们不是。

bpzcxfmw

bpzcxfmw3#

现在我的问题是,如果num和&num[0]相同,那么为什么它们的大小会有差别?
num是一个数组。sizeof对于数组有一个有时令人惊讶的行为,即如果你传递给它一个实际数组,它会告诉你整个数组的存储大小,但如果你传递给它一个元素的地址,它只会告诉你指向数组中某个元素的指针的大小。这可能会导致混乱,因为数组名称在函数调用中降级为指针。
因此,答案是num&num[0]不同-后者是num的第一个元素的地址,去掉了数组总大小的任何信息,这两个东西在许多上下文中是可以互换的,比如调用实际函数,但在调用sizeof时就不能互换(这不是函数,而是编译器处理的特殊关键字)。

rjee0c15

rjee0c154#

哇,一次问了这么多问题: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

相关问题