27-数组的本质分析

注:博客中内容主要来自《狄泰软件学院》,博客仅当私人笔记使用。

测试环境:Ubuntu 10.10

GCC版本:4.4.5

一、数组的概念

1)数组是相同类型的变量的有序集合

      数组示意图:数组包含5个int类型的数据

note:

1) 数组地址a第一个意思:数组名和数组元素首地址都是同一个位置。

2) 数组地址a第二个意思:数组长度。

 

二、数组的大小

1) 数组在一片连续的内存空间中存储元素

2) 数组元素的个数可以显示或隐式指定

int a[5] = {1,2};          //显示指定数组大小
int b[] = {1,2};           //隐式指定数组大小

问题:

1. a[2]、a[3]、a[4]的值是多少? a[2]=0,a[3]=0,a[4]=0

2. b包含了多少个元素?  2个元素 

编程实验
数组的初始化
27-1.c
#include <stdio.h>
int main()
{
    int a[5] = {1, 2};   //剩下的3个元素数值为0
    int b[] = {1, 2};    //可以省略索引值,让编译器自动补充大小
   
    printf("a[2] = %d\n", a[2]);       //0
    printf("a[3] = %d\n", a[3]);       //0
    printf("a[4] = %d\n", a[4]);       //0
   
    printf("sizeof(a) = %d\n", sizeof(a));        //20
    printf("sizeof(b) = %d\n", sizeof(b));        //8 
    printf("count for a: %d\n", sizeof(a)/sizeof(int));    //5
    printf("count for b: %d\n", sizeof(b)/sizeof(int));    //2
   
    return 0;
}

操作:

1) gcc 27-1.c -o 27-1.out编译正确,打印结果:

a[2] = 0
a[3] = 0
a[4] = 0
sizeof(a) = 20    //通过数组名a确定整体数组大小
sizeof(b) = 8     //通过数组名b确定整体数组大小
count for a: 5
count for b: 2 

分析:

         sizeof在编译阶段就计算好数组长度,与运行期无关。

 

三、数组地址与数组名

1) 数组名代表数组首元素的地址(右值)

2) 数组的地址需要用取地址符&才能得到

3) 数组首元素的地址值与数组的地址值相同

4) 数组首元素的地址与数组的地址是两个不同的概念(单个元素和整个数组)

编程实验
数组名和数组地址
27-2.c
#include <stdio.h>
 
int main()
{
    int a[5] = { 0 };
 
    printf("a = %p\n", a);        //数组首元素地址
    printf("&a = %p\n", &a);      //数组地址
    printf("&a[0] = %p\n", &a[0]);//等价于a,都表示数组首元素的地址
   
    return 0;
}

操作: 

1) gcc 27-2.c -o 27-2.out编译正确,打印结果:

a = 0xbfd9a45c    
&a = 0xbfd9a45c
&a[0] = 0xbfd9a45c

四、数组名的盲点

1) 数组名“指向”的是内存中数组首元素的起始位置(指向是为了方便理解)

2) 数组名不包含数组的长度信息

3) 在表达式中数组名只能作为右值使用

4) 只有在下列场合中数组名不能看做指针常量

         - 数组名作为sizeof操作符的参数(表示数组的大小)

         - 数组名作为&运算符的参数 (表示数组的地址,类似type (*a)[n])

实例分析
数组和指针并不相同
27-3.c
#include <stdio.h>
 
int main()
{
    int a[5] = {0};
    int b[2];     //初始值随机
    int* p = NULL;
   
    p = a;        //指针p指向数组a
   
    printf("a = %p\n", a);                  //数组a的首元素地址:0xbfa50ae0
    printf("p = %p\n", p);                  //数组a的首元素地址:0xbfa50ae0
    printf("&p = %p\n", &p);                //数组a的地址:0xbfa50afc
    printf("sizeof(a) = %d\n", sizeof(a));  //20-数组a指定的是数组大小
    printf("sizeof(p) = %d\n", sizeof(p));  //4-指针和数组不同,指针存储的是地址
    ///*
    printf("\n");
 
    p = b;        
   
    printf("b = %p\n", b);                  //数组b的首元素地址:
    printf("p = %p\n", p);                  //数组b的首元素地址:
    printf("&p = %p\n", &p);                //数组b的地址
    printf("sizeof(b) = %d\n", sizeof(b));  //8
    printf("sizeof(p) = %d\n", sizeof(p));  //4
   
    b = a;
    //*/
    return 0;
}

操作:

1) gcc 27-3.c -o 27-3.out编译正确,打印结果:

a = 0xbfae408c
p = 0xbfae408c
&p = 0xbfae4080
sizeof(a) = 20
sizeof(p) = 4

b = 0xbfae4084
p = 0xbfae4084
&p = 0xbfae4080
sizeof(b) = 8
sizeof(p) = 4

分析:

        sizeof(数组名)=数组大小。

 

小结

1) 数组是一片连续的内存空间

2) 数组的地址和数组首元素的地址意义不同

3) 数组名在大多数情况下被当成指针常量处理

4) 数组名其实并不是指针,不能将其等同于指针

发布了40 篇原创文章 · 获赞 1 · 访问量 1755

猜你喜欢

转载自blog.csdn.net/piaoguo60/article/details/104073982
今日推荐