【C】27.数组的本质分析

数组的概念

数组是相同类型变量的的有序集合,在一片连续的的内存空间中存储元素。

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

  • 数组中的元素没有名字
  • 数组名代表首元素的地址

数组的大小

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

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

int a[5] = {1, 2};    // 显示指定个数
int b[] = {1, 2};     // 隐式指定个数
#include <stdio.h>

int main()
{
    int a[5] = {1, 2};
    int b[] = {1, 2};
    
    printf("a[2] = %d\n", a[2]);
    printf("a[3] = %d\n", a[3]);
    printf("a[4] = %d\n", a[4]);
    
    printf("sizeof(a) = %d\n", sizeof(a));
    printf("sizeof(b) = %d\n", sizeof(b));
    printf("count for a: %d\n", sizeof(a)/sizeof(int));
    printf("count for b: %d\n", sizeof(b)/sizeof(int));
    
    return 0;
}

输出结果:

a[2] = 0
a[3] = 0
a[4] = 0
sizeof(a) = 20
sizeof(b) = 8
count for a: 5
count for b: 2

分析:

数组中的元素没有名字,访问是通过下标访问。

当隐式指定数组大小时,编译器会根据元素声明的个数确定大小

技巧

  • 初始化数组每个元素都为0
int32_t a[5]={0};
  • .计算数组元素个数
int a[5] = {1, 2};
int num = sizeof(a)/sizeof(int);

数组地址和数组名

  • 数组名代表数组首元素的地址
  • 数组的地址需要取地址&才能得到
  • 数组首元素的地址(数组名)与数组的地址值相同
  • 数组首元素的地址与数组的地址这两个是不一样的概念,

注意:

地址包涵两个意思:首地址和所占用的内存长度

  • 数组首元素
  1. 地址表示方法:   数组名  或者  &array[0]
  2. 类型:                  type
  • 数组
  1.  地址表示方法:     &array
  2.  类型 :                  type(*)[number]
#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]);
    
    return 0;
}

输出结果:

a = 0x7ffbffffaca0
&a = 0x7ffbffffaca0
&a[0] = 0x7ffbffffaca0

这3个的值都是一样的,但是要注意的时是不一样的概念!!

数组名的盲点

  • 数组名可以看着一个常量指针
  • 数组名指向的是内存中数组首元素的起始位置
  • 数组名不包含数组的长度信息
  • 在表示式中数组名只能作为右值使用
  • 只有在下面的场景中数组名不能看着常量指针
  1. 数组名作为sizeof操作数的参数
  2. 数组名作为&运算符的参数
  • Sizeof(数组名) 得到的结果为这个数组的大小(多少字节)

示例演示

#include <stdio.h>

int main()
{
    int a[5] = {0};
    int b[2];
    int* p = NULL;
    
    p = a;
    
    printf("a = %p\n", a);
    printf("p = %p\n", p);
    printf("&p = %p\n", &p);
    // 指针是变量(就占用内存空间) 所以能取地址(所保存的值和自身的值一般是不一样的)
    printf("sizeof(a) = %d\n", sizeof(a));
    printf("sizeof(p) = %d\n", sizeof(p));
   
    printf("\n");

    p = b;
    
    printf("b = %p\n", b);
    printf("p = %p\n", p);
    printf("&p = %p\n", &p);
    printf("sizeof(b) = %d\n", sizeof(b));
    printf("sizeof(p) = %d\n", sizeof(p));
    
    b = a;  // error
  //  把数组当成常量指针看待,对常量指针进行赋值当成错误
    return 0;
}

注意:

  • 当把数组名看作常量指针,可以用指针的形式访问数组中的元素
  • 数组名在大多数情况下被当成常量指针处理,但是数组就是数组 指针就是指针 不能混淆概念(数组名不是指针)

小结

  • 数组是一片连续的内存空间
  • 数组的地址和数组首元素的地址意义不同
  • 数组名大多数情况被当作常量指针处理
  • 数组名其实不是指针,不能把它等同为指针 
发布了84 篇原创文章 · 获赞 0 · 访问量 758

猜你喜欢

转载自blog.csdn.net/zhabin0607/article/details/103332596