Chinaunix首页 | 论坛 | 博客
  • 博客访问: 28754
  • 博文数量: 8
  • 博客积分: 181
  • 博客等级: 入伍新兵
  • 技术积分: 85
  • 用 户 组: 普通用户
  • 注册时间: 2011-04-13 19:25
文章分类

全部博文(8)

文章存档

2011年(8)

我的朋友
最近访客

分类: C/C++

2011-08-30 09:09:10

    对于一个C编程的程序员来说,几乎是天天与指针和数组打交道。它们之间有非常多的相似之处,以至于很多C编程新手常常认为“数组和指针是相同的”。不幸的是 ,这是一种非常危险的说法,并不完全正确。
 
    数组和指针的不同点。
   
    首先,数组和指针最大的区别是访问数据的方式。众所皆知数组是用来存放数据的,而指针里放的是数据的地址。所以数组直接访问数据,而指针是间接的访问数据。
    
     char a[] = "abcde";
     char *p = "abcde";
   
     对于数组a,假设字符串的首地址是1234,则当我们要求a[2]时,编译器直接进行1234(首地址)+2(偏移量)操作,然后取得地址(1234+2)的内容'c'实现对a[2]的访问。但是对于指针,由于指针里面存放的是字符串首地址,所以必须先取得首地址再进行和数组一样的操作。这里假设指针p本身的地址是1357,编译器会先到1357地址中取得字符串的首地址1234,然后取地址(1234+2)的内容实现p[2]的操作(下面将会讲到此操作)。
 
    另外一个重要的区别,数组是系统在初始化时自动为我们分配空间的,一般放在栈区, 且由系统自动对它删除。而指针是程序员本身用malloc()函数动态分配到堆区,并用free()函数将其释放。 数组的大小初始化后是固定的且数据类型必须相同。
    在上面的列子中可以看出数组和指针都可以在它们的定义中用字符串常量进行初始化。尽管看上去一样,底层的机制却不同。定义指针时,编译器并不为指针指向的对象分配空间,它只是分配指针本身的空间。在ANSI C中,初始化指针时所创建的字符串常量被定义为只读,不能对它进行修改。与指针相反,字符串常量初始化的数组是可以修改的。比如:strncpy(a,"fdg",3)。就将数组a的值修改为:"fdgde"。
 
   
    数组和指针的相同点。
 
    在《The Bell System Technical Journal》中记录道,“包含一个通用规则,就是当一个数组名出现在一个表达式中时,它会被转换为一个指向该数组的第一个元素的指针。”
    C语言标准对什么时候数组和指针是相同的作了如下说明:
    规则1.表达式中的数组名(与声明不同)被编译器当作一个指向该数组第一个元素的指针
    规则2.下标总是与指针的偏移量相同。
    规则3.在函数参数的声明中,数组名被编译器当作指向 该数组第一个元素的指针。
   
    因此它们的相同点1.“表达式中的数组名”就是指针。例如:
 
    int a[] = {1,2,3,4,5};
    int *p, i = 2;
   
    就可以用以下几种方法来访问a[i]:
 
    1.    p = a;         p[i];
    2.    p = a;         *(p+i);
    3.    p = a + i;     *p;
 
    但是爱钻牛角尖的人可能会发现并不是所有情况都能将数组当作是指针。例如:
 
    1.用sizeof()求数组的大小时得到的是整个数组的大小,而不是指针指向的第一个元素的大小,更不是指针的大小(4个字节)。
    2.要使用&操作符取数组的地址,这里就很明显的看出数组名并没有转换成指针。
    3.数组在用字符串常量初始化时是赋值操作,也算是个表达式,当是右值却不是变量的地址,而是字符串本身。
 
    对于这些情况不能不说是C语言没有做好,毕竟C语言还是存在很多的漏洞,所以就让我们自己注意点。
 
    还有的共同点是C语言把数组下标当作指针的偏移量。这就是前面所用的a[2]来访问数据。C语言将数组下标当作指针的偏移量是从B语言继承而来的技巧,按照人们的常规思维在运行时增加对C语言数组的下标范围检查是很不切实际的,这样做就必须执行取下标操作。为了提高效率C语言将下标当作偏移量从而绕过下标操作符。在这种情况下,数组下标范围的检测则不能检测所有对数组访问的情况。尽管在处理一维数组时,指针并不见得比数组更快,但是C语言将数组下标改写成指针的偏移量的根本原因是指针和偏移量是底层硬件所使用的基本模型。
  
阅读(1186) | 评论(0) | 转发(0) |
0

上一篇:Linux二十周年回顾:与微软的那些往事

下一篇:没有了

给主人留下些什么吧!~~