Saturday, May 03, 2008

Differences of array and pointer in C/C++

(1) Array

int main(){
    char *p = "hello,world";
    char *p2 = "hello,worldc";
    char str[] = "hello,world";
    char str2[] = "hello,world";    
    printf("%x %x %x %x\n", p, p2, str, str2);

}

Sample output(compiled with GCC 4.1.2 on Ubuntu 6.06.1LTS):

804856c 8048578 bf879674 bf879668

Conclusions:
<1> Strings pointed by pointers p and p2 are allocated in different places from strings of str and str2. The first and second strings are allocatd to static memory area and these two strings can not be modified. So the following statement makes the program crash(run time error instead of compilation time):
    p[0] = 'd'
The third and fourth strings are allocated on stack.  They can be modified. They just exist in current function call and after this function is executed they are discarded and should not be referenced any more.
<2> Pointers can be modified arbitrarily while array variables can not be modified.
Following code is illegal:

    char str[] = "hello,world";
    char str2[] = "abcdefgh";
    str = str2;    //illegal, can not be compiled successfully.
str++; //illegal
str+1; //legal, just like an ordinary addition.

In other words, array name is a reference to an array and it represents the array.  It is kind of a contant.
<3> Array name cannot be used a left value. Array name can be used as pointer if it acts as right value. Pointer can not be cast to array!!!
<4> Apply sizeof to array name, you will get size of the array. Apply sizeofi to a pointer, you will get size of the pointer(generally, four bytes).
<5> Array must be initialized and corresponding memory is allocated.
<6> void function(type array[]) is equivalent to void function(type *pointer).

数组要么在静态存储区被创建(如全局数组),要么在栈上被创建。数组名对应着(而不是指向)一块内存,其地址与容量在生命期内保持不变,只有数组的内容可以改变。
指针可以随时指向任意类型的内存块,它的特征是“可变”,所以我们常用指针来操作动态内存。指针远比数组灵活,但也更危险。
不能对数组名进行直接复制与比较。示例7-3-2中,若想把数组a的内容复制给数组b,不能用语句 b = a ,否则将产生编译错误。
当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针.
对数组名sizeof()得到的是数组所占的大小,而对指针sizeof()得到的是指针内容所占的字节数。
数组定义时必须初始化并分配空间,而指针定义时可以不初始化。
如果将数组或指针作为自定义函数的形参,此时数组名和指针完全等价.在函数体内可以用数组名进行自增或赋值等运算,因为在一般的编译程序中,将函数的形参数组编译成指针.既f(char Data[])====>f(char *Data)