数组变量与指针

Posted jasonljy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数组变量与指针相关的知识,希望对你有一定的参考价值。

背景:完全的C初学者。。试图搞清楚数组的概念,做了一些小试验,查了一些解释,合成此文。

我们说数组变量相当于常量指针,那么实际它就是常量指针名吗?

简单试验:

技术分享图片
 1 #include <stdio.h>
 2 
 3 int main() {
 4     int a; //声明int变量
 5     printf("变量的地址:%p
",&a); //声明变量时,申请内存地址
 6     printf("变量占位:%d
",sizeof(a)); //根据类型决定分配空间
 7     // printf("变量的值:%d
",a);  //报错,因为没有放入值
 8     a = 9;
 9     printf("变量的值:%d

",a);
10 
11     
12     int *p; //声明指针变量
13     printf("指针变量的地址:%p
",&p);  
14     printf("指针变量占位:%d
",sizeof(p));
15     // printf("指针变量指向:%d
",*p); //报错,因为没有放入值
16     p = &a;
17     printf("指针变量的值:%p
",p);
18     printf("指针变量指向:%d

",*p); 
19     
20     
21     int s[4]={5}; //声明数组变量
22     printf("数组变量的地址:%p
",&s);
23     printf("数组变量的地址+1:%p
",&s+1);
24     printf("数组变的地址占位:%d
",sizeof(&s));  //sizeof(地址)
25     printf("数组变量的值:%p
",s); //数组变量的值的自己的地址!是一个特殊的指针!
26     printf("数组变量的值+1:%p
",s+1);
27     printf("数组变占位:%d
",sizeof(s));  //sizeof(地址)?
28     
29     
30     printf("数组变量首元素的地址:%p
",&s[0]); //s和s[0]地址相同!
31     printf("数组变量次元素的地址:%p
",&s[1]); //数组是变量的容器
32     printf("取数组首元素:%d
",s[0]);
33     printf("对数组变量解指针操作:%d
",*s);  //s指向的东西就是s[0]!
34     printf("数组元素占位:%d

",sizeof(s[0]));
35 
36  
37     
38     //指针变量和数组变量互相s赋值
39     int b=88;
40     int *const p2=&b; //常量指针必须在声明的时候初始化!
41     p = s; //可以改变指针p的值
42     // p2 = p; //常量指针不可修改!
43     // s = &b; //数组变量不可修改!
44     int s2[5];
45     printf("数组变量s2的地址:%p
",&s); 
46     printf("数组变量的值:%p
",s); //地址相同??
47     // s2 = s; //数组变量不可修改!
48      
49     return 0;
50 }
View Code

输出:

技术分享图片

技术分享图片

可以看出来:

  • 数组变量符合指针的定义
  • 数组变量的值就是数组首元素的地址
  • 数组变量不可修改,类似于常量指针

其中不解的是

  • 用&取数组变量的地址,发现与数组首元素的值的地址相同,即s与&s的值相同。
  • 如果数组变量就是指针的话,那么数组变量的值为其首元素的地址,而它自己不应该放在另一个地址吗?(就像上面的指针变量p一样)

于是,查阅了一下,这个问题大致是这样理解的

  • arr 本身是左值(但不可仅凭此表达式修改),指代数组对象。不过 arr 会在大多数场合隐式转换成右值表达式 &(arr[0]) 。为指针类型,指向 arr[0] 。
    &arr 是右值表达式,为指针类型,指向 arr 本身。简单来说就是 arr 本身不是地址而是指代整个数组,只不过会隐式转成指针罢了arr (转换后)和 &arr 类型不同数值相等是因为 arr 和 arr[0] 地址相同,这里地址指首地址。【转自知乎-暮无井见铃

另有一份总结:

  • 数组地址与数组名:
    • 数组名代表数组首元素的地址(a);
    • 数组的地址需要用取地址符&才能得到(&a);
    • 数组首元素的地址值与数组的地址值相同
    • 数组首元素的地址数组的地址两个不同的概念
  • 数组名的盲点:
    • 数组名可以看做一个常量指针;
    • 数组名“指向”的是内存中数组首元素的起始位置;
    • 在表达式中数组名只能作为右值使用下
  • 下列场合中数组名不能看做常量指针:
    • 数组名作为sizeof操作符的参数;
    • 数组名作为&运算符的参数

    技术分享图片

验证s与&s类别不同

  s与&s值相同,但s+1与&s+1值不同


以上是关于数组变量与指针的主要内容,如果未能解决你的问题,请参考以下文章

指针数组与指针变量

指针与数组

指针与数组

指针与数组

数组变量与指针

数组与指针