登录站点

用户名

密码

数组名a和&a的异同

5已有 970 次阅读  2009-12-31 13:14
flyreally原创,希望对新手能有所帮助。
 
    写这篇文章纯粹是因为WJ的那篇关于C语言考察题目,本人比较菜,第一次看到如下代码
    char a[] = "abcd";
    printf("%c, %c\n", *(a + 1), *(&a + 1));
    看完之后觉得输出结果应该是b, b,但实际却不是,纳闷了好久,一直搞不明白,最近看书有点想法,总算搞明白了,说说自己的想法吧。
    我先回顾几个概念:
    1.指针:指针就是内存单元的地址,是一个常量。
    2.指针变量:用于存储指针的变量,是一个变量。
    3.数组名:数组名是一种特殊的指针(数组名和指针的异同请看《C专家编程》),代表的该数组在内存中的起始位置。
    我们再看看指针可以有哪些加减运算
    1.指针的加法运算:两个指针变量相加无意义;指针跟int、long、char型变量或整形常量相加,代表从当前指针的偏移量,具体偏移多少,由指针所指向的数据类型决定。
    2.指针的减法运算:两个指针变量相减,相当于求这两个指针的偏移量,大多用于指向同一数组的两个指针变量的运算。
    我们还需要知道不同数据类型在内存中所占用的空间,以32位平台为例说明。
    int占4个字节,指针变量占4个字节,char占一个字节,其他的就不列举了。指针变量为什么占4个字节呢,因为我们的系统是32位,也就是系统的寻址能力是32位,以XP来说,XP的寻址能力就是2^32=4GB,每个内存单元的地址就是32位,所以就是4个字节,当然,这是微机原理中的内容了 。
    了解了这些,我们言归正传。
    我们都知道,数组名是一个特殊的指针,代表的是该数组在内存单元中的首地址,而且《C专家编程》中提到,数组名在表达式中跟指针等价,那么为什么a + 1&a + 1的指向不同呢?
    我在前面提到,指针和int、long、char型变量或整形常量相加减的时候,就是求相对于当前指针的偏移量,而偏移量具体是多少,由该指针所指向的数据类型决定。比如说:
    int *p = 1000;   //此处仅为说明异同而如此赋值
    char *q = 2000;
    p + 1q + 1的结果相比,偏移量是截然不同的,p + 1指向1004(32位平台),而q + 1指向2001,这就说明了,偏移量的多少,完全由指针所指向的数据类型决定,偏移量就等于对指针所指向的数据类型求sizeof
    现在我们就可以明白为什么对于数组a,a + 1的指向的地址跟&a + 1不同了,在表达式中,数组名等同于指针,所以数组名a就相当于一个字符型指针,a的数据类型也就是char *,它所指向的数据类型是char,a相当于一个字符型指针,那么&a呢?它就相当于一个二级指针,指向字符型数组的指针,所以&a的数据类型也就是char **,它所指向的数据类型是char []。到此为止,我们就明白了为什么a + 1&a + 1所指向的地址不同了。假设数组名a所指向的地址是2000,那么a + 1指向的是2001,也就是数组a中的第二个字符*(a + 1),&a + 1指向的就是2005,也就是偏移量为1 * sizeof(a) = 5也就是数组a之后的第1个字符*(a + 5)。注:*(a + 5)已经超出了数组a的范围
     所以,以后遇到这种求指针偏移量的问题,可以如此计算:sizeof(指针所指向的类型) * N
     到此为止,我们应该可以彻底明白了,原来指针的运用这么灵活而又复杂。
     最近看书感触很深,给大家推荐几本学C语言必读的书籍,《C缺陷与陷阱》、《C专家编程》、《C和指针》、《高质量C++/C编程》(林锐博士的著作),这几本书除了《C和指针》我都看了,写的确实太好了。
 
   
   
    
    

上一篇: 4*4矩阵键盘驱动程序 下一篇: 用MC9S12XS128实现超声波测距(使用PIT模块定时)

分享 举报

发表评论 评论 (9 个评论)

  • whut_wj 2010-01-02 00:07
    支持小杨!这种刨根问底的精神太强了。
    多多交流C的东西,很有意思的。
    我是在做socket中发现报文长度处理都用了这种方法,以前在处理bmp图像中没注意。
    我感觉,其实很多东西都是细节,一但熟了之后,编程时候脑子里会蹦出一串代码。
  • 兰州交通大 2010-01-02 13:39
    whut_wj: 支持小杨!这种刨根问底的精神太强了。
    多多交流C的东西,很有意思的。
    我是在做socket中发现报文长度处理都用了这种方法,以前在处理bmp图像中没注意。
    我感觉
    谢谢WJ大哥,我做过的东西还是太少,网络编程更没接触过,以后还要多多向WJ大哥学习啊。新年快乐哦
  • 李凯 2010-01-09 14:29
    小弟初学,想请问一下“也就是偏移量为1 * sizeof(a) = 5”是怎么算出来的??谢谢!
  • 兰州交通大 2010-01-09 20:09
    xiaokk: 小弟初学,想请问一下“也就是偏移量为1 * sizeof(a) = 5”是怎么算出来的??谢谢!
    sizeof(a) = 5,是因为char a[] = "abcd";,数组的大小为5
  • 蓝牙 2010-03-19 21:08
    那输出结果是什么呢?
  • 蓝牙 2010-03-19 21:11
    输出为b,}
  • 蓝牙 2010-03-19 21:13
    为什么输出这样呢。不明白
  • 醉八仙 2011-09-16 12:14
    要好好的研究一下 好好学习一下啦
  • porereadi 2012-06-07 19:40
涂鸦板