指针和数组的相同与不同

出自:c专家编程.P199

在实际应用中,数组和指针可以互换的情形要比两者不可互换的情形更为常见。让我们分别考虑“声明”和“使用”这两种情况。声明本身还可以进一步分为3种情况:

·外部数组的声明;

·数组的定义(定义是声明的一种特殊情况,它分配内存空间,并可能提供一个初始值);

·函数参数的声明;

                                        (1) extern,如extern char a[];

                                         不能改写为指针的形式 

                1.声明                     定义,如char a[10];

                                         不能改写为指针的形式

数组

                                        (2) 函数的参数,可以随意选择数组的形式或者指针的形式  

 


              2. 在表达式中使用      (1) c=a[i],可以随意选择数组

                                         形式或者是指针形式

 

也既是:作为函数参数时、在语句或表达式中使用数组时,我们可以采用数组或者指针的任何一种形式,除此之外的其他情况下,指针和数组不要互换。下面就数组和指针相同的情况做详细的说明:

 

·规则1、表达式中的数组名被编译器当作一个指向该数组第一个元素的指针。

假如我们声明:

int a[10];

int *p = a;

就可以通过一下任何一种方式来访问a[i]

p[i]       *( p + i )        *( a + i )      ·····

事实上,可以采用的方法很多。对数组的引用如a[i] 在编译时总是被编译器改写成*(a+i)的形式,C语言标准要求编译器必须具备这个概念性的行为。

编译器自动把下标值的步长调整到数组元素的大小。如果整型数的长度是4个字节,那么a[i+1]a[i]在内存中的距离就是4。对起始地址执行加法操作之前,编译器会负责计算每次增加的步长。这就是为什么指针总是有类型限制,每个指针只能指向一种类型的原因所在,因为编译器需要知道对指针进行解除引用操作时应该取几个字节,以及每个下标的步长应取几个字节。

 

·规则2、下标总是和指针的偏移量相同。

把数组下标作为指针加偏移量是c语言从BCPL(C语言的祖先)继承过来的技巧。在人们的常规思维中,在运行时增加对c语言下标的范围检查是不切实际的。因为取下标操作只是表示将要访问该数组,但并不保证一定要访问。而且程序员完全可以使用指针来访问数组,从而绕过下标操作符。在这种情况下,数组下标范围检测并不能检测所有对数组的访问的情况。事实上,下标范围检测被认为不值得加入到c语言当中。

还有一个说法是,在编写数组算法时,使用指针比使用数组更有效率。这个颇为人们所接收的说法在通常情况下是错误的。使用现代的产品质量优化的编译器,一维数组和指针引用所产生的代码并不具有显著的差别。不管怎样,数组下标是定义在指针的基础上,所以优化器常常可以把它转化为更有效率的指针表达式,并生成相同的机器指令。

 

 

·规则3、在函数参数的声明中,数组名被编译器当作指向该数组第一个元素的指针。

    在函数形参定义这个特殊情况下,编译器必须把数组形式改写成指向数组第一个元素的指针形式。编译器只向函数传递数组的地址,而不是整个数组的拷贝。这种转换意味着在声明函数的时候,以下三种形式都是合法的(同时无论实参是数组还是真的指针也都是合法的)

my_function( int *turnip ) {···}

my_function( int turnip[] ) {···}

my_function( int turnip[200] ) {···}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值