透过一些实例理解数组和指针的一些细节

来源:互联网 发布:淘宝二手ipad哪家靠谱 编辑:程序博客网 时间:2024/05/16 14:47

   一、一个编译不过的小程序

我们先来看一个小程序:

    

void test_f2()                  {    char str[]=”test string”;     int i;    for(i = 0; i<4; i++, str++)    {        *str=’a’;    }}


编译:$ gcc -g -o cHAR cHAR.c

cHAR.c: In function ‘test_f2’:
cHAR.c:11: error: lvalue required as increment
opera

这说明: 数组名是一个常量指针,并不是一个左值

      数组名不是常量指针的情况只有两种,就是当数组名是sizeof和&的操作数时,前者产生整个数组的占用的字节数,后者产生一个指向数组的指针。

    注意:数组和指针并不是相同的:

   声明数组时,同时分配了一些内存空间,用于容纳数组元素,但是当我们声明一个指针时,只分配了用于容纳指针本身的内存空间。

    什么时候数组和指针相同呢?
c语言标准对此做了如下说明
规则1.表达式中的数组名被编译器当作一个指向该数组的一个元素的指针
规则2.下标总是与指针和偏移量相同

规则3.在函数参数的声明中(形式参数),数组名被编译器当作指向该数组第一个元素的指针

 

二、字符数组和指向字符串常量的指针

char message1[] = "hello"; 

//message1是个数组,message1也是一个常量指针,不能改变message1的指向,"hello"是数组的初始化列表,可以通过下标或者间接操作来改变值

char *message2 = "hello"; 

//message2指向字符串常量,message2是一个变量指针,可以改变message2的指向。不能通过下标或者间接操作来改变值。如果硬要改变的话是编译通过但运行出错

 

三、数组指针和指针数组

          数组名的指针,即数组首元素地址的指针。即是指向数组的指针。
例:int (*p)[10]; p即为指向数组的指针,又称数组指针。
      
        数组指针是指向数组首元素的地址的指针,其本质为指针;
       指针数组是数组元素为指针的数组(例如 int *p[3],定义了p[0],p[1],p[2]三个指针),其本质为数组.
    
        为了能更好地理解数组指针,与普通指针及二级指针的区别,下面举例说明一下。
        例如:
        {
             int a[4][5];
             int (*p)[5]=a;
        }
      这里a是个二维数组的数组名,相当于一个二级指针常量;p是一个指针变量,它指向包含5个int元素的一维数组,此时p的增量以它所指向的一维数组长度为单位;p+i是二维数组a的i行的起始地址,*(p+2)+3表示a数组2行3列元素地址(第一行为0行,第一列为0列),*(*(p+2)+3)表示a[2][3]的值。

 

原创粉丝点击