如何在C编译器内部处理数组和指针类型? (INT *一个;与int类型的[]) [英] How are array and pointer types handled internally in C compilers? ( int *a; vs. int a[]; )

查看:152
本文介绍了如何在C编译器内部处理数组和指针类型? (INT *一个;与int类型的[])的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要权威渠道的语言律师。

看看下面的测试程序,它在GCC完全编译:

 的#include<&stdio.h中GT;
无效美孚(INT *一){
    一个[98] = 0xFEADFACE;
}无效杆(INT B〔]){
    *(B + 498)= 0xFEADFACE;
}INT主(INT ARGC,字符** argv的){诠释[100],B [500],* a_p;*(A + 99)= 0xDEADBEEF;
*(B + 499)= *(A + 99);富(一);
杆(二);输出(一个[98] ==%X \\呐[99] ==%X \\ N,一个[98],A [99]);
的printf(B [498] ==%X \\ NB [499] ==%X \\ N,B [498],B [499]);a_p = A + 98;
* a_p = 0xDEADFACE;输出(一个[98] ==%X \\呐[99] ==%X \\ N,一个[98],A [99]);}

它产生的输出我预计:

 匿名@匿名:〜/学习/ TEST_ code $的gcc -o arrayType.c arrayType中
匿名@匿名:〜/学习/ TEST_ code $ ./arrayType
一个[98] == FEADFACE
一个[99] == DEADBEEF
B〔498] == FEADFACE
B〔499] == DEADBEEF
一个[98] == DEADFACE
一个[99] == DEADBEEF

是A和B中的相同类型?为为int * A 处理为相同类型的 int类型的[] 内部编译器?

从视图实际出发INT [100],B [500],* a_p,b_a []; 似乎都为同一类型。这是我很难相信,编译器是不断的调整的这些类型在我上面例子中的各种情况。我很高兴的证明的错误。

有人能解决这个问题,我的明确和详细


解决方案

  

是A和B中的相同类型?为int *作为一个同类型的处理为int的编译器[]内部?


comp.lang.C 常见问题


  

......每当一个阵列出现在一个前pression,编译器隐式生成一个指向数组的第一个元素,就像程序员写了&安培; A [0]。 (唯一的例外是当阵列是一个sizeof的或放的操作;操作者,或对一个字符数组......一个字符串初始化)


  
  

...给定阵列的和指针p,形式的[I]的前pression导致阵列衰变成一个指针,按照上述的规则,然后将刚才下标作为将是在恩pression页记载的指针变量[I](尽管最终存储器访问将是不同的...


。鉴于声明

 的char a [] =你好;
的char * p =世界;


  

...当编译器看到前pression A [3] ,它发出code的位置开始,将过去三个吧,这里面提取的字符。当看到前pression P [3] ,它发出code的位置开始 P ,取指针值出现,添加三个指针,最后取字符指出。 换句话说, A [3] 是两岸三地过去(开始)命名的对象 A ,而 p [3] 是两岸三地近对象指向 p


重点是我的。最大的区别似乎是指针被取出时,它的一个指针,而没有指向去取,如果它是一个数组。

I need a language lawyer with authoritative sources.

Take a look at the following test program which compiles cleanly under gcc:

#include <stdio.h>


void foo(int *a) {
    a[98] = 0xFEADFACE;
}

void bar(int b[]) {
    *(b+498) = 0xFEADFACE;
}

int main(int argc, char **argv) {

int a[100], b[500], *a_p;

*(a+99) = 0xDEADBEEF;
*(b+499) = *(a+99);

foo(a);
bar(b);

printf("a[98] == %X\na[99] == %X\n", a[98], a[99]);
printf("b[498] == %X\nb[499] == %X\n", b[498], b[499]);

a_p = a+98;
*a_p = 0xDEADFACE;

printf("a[98] == %X\na[99] == %X\n", a[98], a[99]);

}

It produces the output I expect:

anon@anon:~/study/test_code$ gcc arrayType.c -o arrayType
anon@anon:~/study/test_code$ ./arrayType 
a[98] == FEADFACE
a[99] == DEADBEEF
b[498] == FEADFACE
b[499] == DEADBEEF
a[98] == DEADFACE
a[99] == DEADBEEF

Are a and b the same type? Is int *a handled as the same type as int a[] internally in the compiler?

From a practical point of view int a[100], b[500], *a_p, b_a[]; all seem to be the same type. It's hard for me to believe that the compiler is constantly adjusting these types in the various circumstances in my above example. I'm happy to be proven wrong.

Can someone settle this question for me definitively and in detail ?

解决方案

Are a and b the same type? Is int *a handled as the same type as int a[] internally in the compiler?

From the comp.lang.C FAQ:

... whenever an array appears in an expression, the compiler implicitly generates a pointer to the array's first element, just as if the programmer had written &a[0]. (The exceptions are when the array is the operand of a sizeof or & operator, or is a string literal initializer for a character array...)

... Given an array a and pointer p, an expression of the form a[i] causes the array to decay into a pointer, following the rule above, and then to be subscripted just as would be a pointer variable in the expression p[i] (although the eventual memory accesses will be different ...

Given declarations of

char a[] = "hello";
char *p = "world";

... when the compiler sees the expression a[3], it emits code to start at the location a, move three past it, and fetch the character there. When it sees the expression p[3], it emits code to start at the location p, fetch the pointer value there, add three to the pointer, and finally fetch the character pointed to. In other words, a[3] is three places past (the start of) the object named a, while p[3] is three places past the object pointed to by p.

Emphasis is mine. The biggest difference seems to be that the pointer is fetched when it's a pointer, while there is no pointer to fetch if it's an array.

这篇关于如何在C编译器内部处理数组和指针类型? (INT *一个;与int类型的[])的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆