关于数组与指针的区别

最近在动手写一个RMI类似的库,刚刚开始,在实现一个类的时候,注意到了以前被忽略的问题。

指针和数组,绝对不是一回事。

程序的原型是这样的:

bool copy(uint8_t** data , uint32_t len);
后来我使用的时候,定义了一个uint8_t的数组,想通过&<数组名>的方式传递一个指针的指针,可耻的失败了。

调试一番后,果断发现传进去的值,居然不是我想的指针的指针,而是数组的首地址。然后把数组换成了指针,获得了期望的结果。

测试程序如下:

#include <stdio.h>
#include <stdint.h>

int main( int argc , char** argv)
{
	int   data[4] = {0};
	char* str = "mm test";
	printf("data is %d\n" , data);
	printf("data addr is %d\n" , &data);
	printf("str is %d\n" , str);
	printf("str addr is %d\n" , &str);
	return 0;
}

     结果是:

     

     从程序打印的结果就可以看出指针和数组完全是两个不同的东东。

     为什么会有这样的差异,在google了一番之后,找到了满意的答案。

     http://www.cnblogs.com/csyisong/archive/2010/03/18/1688877.html

     以下内容为转载:

    1 指针和数组的区别
    指针和数组的分配
    数组是开辟一块连续的内存空间,数组本身的标识符(也就是通常所说的数组名)代表整个数组,可以使用sizeof来获得数组所占据内存空间的大小(注意, 不是数组元素的个数,而是数组占据内存空间的大小,这是以字节为单位的)
    2 空间的分配
    这里又分为两种情况:

    第一,如果是全局的和静态的
    char *p = “hello”;
    这是定义了一个指针,指向rodata section里面的“hello”,可以被编译器放到字符串池。在汇编里面的关键字为.ltorg。意思就是在字符串池里的字符串是可以共享的,这也是 编译器优化的一个措施。
    char a[] = “hello”;
    这是定义了一个数组,分配在可写数据块,不会被放到字符串池。

    第二,如果是局部的
    char *p = “hello”;
    这是定义了一个指针,指向rodata section里面的“hello”,可以被编译器放到字符串池。在汇编里面的关键字为.ltorg。意思就是在字符串池里的字符串是可以共享的,这也是 编译器优化的一个措施。另外,在函数中可以返回它的地址,也就是说,指针是局部变量,但是它指向的内容是全局的。
    char a[] = “hello”;
    这是定义了一个数组,分配在堆栈上,初始化由编译器进行。(短的时候直接用指令填充,长的时候就从全局字符串表拷贝),不会被放到字符串池(同样如前,可 能会从字符串池中拷贝过来)。注意不应该返回它的地址

    继续在网上看,后面看到了一个程序,可以更深刻地认识到数组和指针的区别。
    以下程序的打印值是什么?
          int c[5] = {1,2,3,4,5};

          int *ptr = (int *)(&c +1);

          printf("%d %d\n", *(c +1), *(ptr-1));
   如果答案是2,1,那就错了 , 答案是2,5。为什么?关键就是(&c+1)。
  上面已经说到,数组本身的标识符代表整个数组。并且数组和指针的分配根本不是一样的。可以这么理解,数组定义的时候,数组名代表一整块区域,因为没有任何指针指向数组所在的内存区域,所以&<数组名>只能返回数组的首地址。而在定义指针的时候,指针本身是占据一块4字节的内存的,这块内存的地址,就是指针的指针。
   (&c+1)实际得到的是(&c+sizeof(c))。看到这里是不是想起了什么?假设我们有个int*的指针ptr , ptr+1不就是指向下一个int的指针吗?原来对于数组我们应该把它当做类型,这才是正确的。是的,它和指针不是一回事,它其实应该是像int char short这样的类型。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章