2011-08-27 88 views
11

我在C书中读到,对于数组num[7],术语num等于&num[0]。这个概念对我来说工作得很好,但是当我写下如下所示的程序时,我再次感到困惑。给定`int 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

然后我试图2-d阵列是这样的:

#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的含义。而且我再次能够看到ss[0][0]不相同。我用Dev C++ 4.9.9.2版本来运行所有的程序。我想在这三类术语中清楚。

+2

阅读有一个专门对这个问题一整节的C FAQ:http://c-faq.com/aryptr/index.html – AnT

+0

@good问题为初学者!好友 – niko

回答

2

哇,这是一个很大的一气呵成的问题:P

首先,我会尝试这个输出解释给你听:

4 4 4 
    4 28 4 
    2293536 21 21 

sizeof()是在C一元运算符。代码编译时将其替换为整数,而不是在运行时。因此,编译器会将您的printf文字性地更改为:

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被定义用于数组的原因。所有其他元素给你一个为(int *)除外的sizeof(& NUM),让你的大小(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 
3

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

请注意,如果需要,可将num转换为int*,值为&num[0]。当然,转换与等同不一样。你会发现数组和指针之间的混淆很奇怪,因为人们不断重复数组是指针的错误。他们不是。

3

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

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

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

6

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

鉴于

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

然后

  • num已键入int[]因为其内存在的地方被分配整数声明数组。请注意,它确实有而不是的类型为int*,如果您使用它,则会发生这种情况。
  • 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 [4] [2] = {{1234,56},{1235,57},{1236,58},{1237,59}};

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

你会发现,s&s[0]&s[0][0]都指向相同的内存位置,但是,你注意到了,sizeof值会有所不同。

+0

@pst,对,我做了太多的假设。它包含7个四字节整数。是的,OP可能位于具有不同大小整数的机器上。 –

+0

更好,还有+1:p – 2011-08-27 21:02:52