Arrays and Pointers

There are a large amount of C programmers who will consider arrays and pointers as the same thing, or at least they have the same usage, especially those beginners. But actually that is not correct! I am sure somebody will come out to oppose it, and their reason seems to be sufficient. Suppose we declare an array containing 10 integers: int a[10], and a pointer referring to an integer: int *pa. Now we can iterate over the array a using a for-loop and the subscript operation like this:

#include  < stdio.h >

main()
{
    
int a[10];
    
int i;
    
for(i = 0; i < 10; i++)
    
{
        a[i] 
= i;
    }

    
return 0;
}

Also, we can do it using the pointer pa. But first of all, the correct address should be assigned to the pointer:

pa  =  a;
for (i  =   0 ; i  <   10 ; i ++ )
{
    
*(pa + i) = i;
}

Another way to express this is to use the pointer just as the array name, with the subscript operation:

pa  =  a;
for (i  =   0 ; i  <   10 ; i ++ )
{
    pa[i] 
= i;
}

So somebody comes to the conclusion: arrays and pointers are just the same, because they can replace each other without any change.

Well in this case, the array and the pointer can replace each other without any change, or say, any change in the surface which is more accurate. But inside, the dereferences of the these two things are a little bit different. Let's talk more about that. First of all, the array name can't be assigned to any address or changed, while the pointer can be set to any address, as long as it is not a const pointer. Almost everybody knows it, including the beginners. Secondly, the array name stands for the starting address of the whole array, you can regard it as an identifier other than a variable, but the pointer is surely a variable. It may contains the starting address of some array, while it has got itself an address. Thirdly, which is the most important, if we declare an array, the starting address will be known during the comile time, while the value of a pointer will be got during the run time. What is known in the compile time about the pointer is the address of itself. So when we want to iterate over the array, the dereference mechanisms are different. For the array name, two steps are needed: first add the offset, which is represented by the variable i, to the address of the array(this is known in the compile time, still remember?), second get the content(i.e. the ith element in the array) from the new address. For the pointer, three steps are needed: first get the pointer's value(the starting address of the array) from its own address, second add the offset to its value, third get the content from the new address. See, one more step for the pointer's dereference, and this always cause a confusion.

In the case we discussed above, the compiler and the runtime will handle this difference automatically. But in most cases, it is not what you expected. For example, we have already define an array in one file: int a[10], and we want to use this array in another file. Generally we just use "extern" to declare it in another file: extern int a[10](the size of the array can be omitted). But if you code like this: extern in *a, it won't pass the compilation(in some old compilers, this is OK, but the result of dereferencing the pointer is undefined).

Sometimes, knowing why you can't do one thing is as important as knowing why you can do one thing.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值