zoukankan      html  css  js  c++  java
  • 第27课

    第27课 - 数组的本质分析

    1. 数组的概念

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

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

     

    2. 数组的大小

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

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

    观察下面两个数组,思考两个问题: a[2],a[3],a[4] 的值是多少?   b包含了多少个元素?

        

    【数组的初始化】

     1 #include <stdio.h>
     2 
     3 int main()
     4 {
     5     int a[5] = {1, 2};  // 编译器将未初始化的元素初始化为0
     6     int b[] = {1, 2};   // 数组未指定大小 ==> 编译器根据数组初始化的情况计算其大小(占用的空间最小)
     7 
     8     printf("a[2] = %d
    ", a[2]);    // 0
     9     printf("a[3] = %d
    ", a[3]);    // 0
    10     printf("a[4] = %d
    ", a[4]);    // 0
    11 
    12     // sizeof(数组名) ==> 计算数组的大小
    13     printf("sizeof(a) = %zu
    ", sizeof(a)); // 20
    14     printf("sizeof(b) = %zu
    ", sizeof(b)); // 8
    15 
    16     printf("count for a: %zu
    ", sizeof(a)/sizeof(a[0]));   // 5
    17     printf("count for b: %zu
    ", sizeof(b)/sizeof(b[0]));   // 2
    18 
    19     return 0;
    20 }

    3. 数组地址与数组名

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

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

    (3)数组首元素的地址值与数组的地址相同但是数组首元素的地址与数组的地址是两个不同的概念。

            我们通常所说的地址包括两个方面的概念:起始地址所占用内存空间的大小。数组名仅仅对应数组一个元素那么大的内存,而数组的地址对应整个数组所占用的内存空间。

    【数组名和数组地址】

     1 #include <stdio.h>
     2 
     3 int main()
     4 {
     5     int a[5] = {0};
     6 
     7     printf("a = %p
    ", a);          // 0x7ffc7425dbb0
     8     printf("&a = %p
    ", &a);        // 0x7ffc7425dbb0
     9     printf("&a[0] = %p
    ", &a[0]);  // 0x7ffc7425dbb0
    10 
    11     return 0;
    12 }

    4. 数组名的盲点

    (1)数组名可以看作一个指针常量;注意这里只是说"可以看作",并非是真正的指针常量

    (2)数组名"指向"的是内存中数组首元素的起始位置

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

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

    (5)只有在下列场合中数组名不能看作常量指针

    • 数组名作为作为 sizeof 操作符的参数,表示整个数组的大小
    • 数组名作为 & 运算符的参数,表示整个数组的地址

    【数组和指针并不相同】

     1 #include <stdio.h>
     2 
     3 int main(){
     4     
     5     int a[5] = {0};
     6     int b[2];
     7     int* p = NULL;
     8 
     9     p = a;
    10 
    11     printf("a = %p
    ", a);    // 0x7ffe40054a70, 数组a首元素的地址
    12     printf("p = %p
    ", p);    // 0x7ffe40054a70
    13     printf("&p = %p
    ", &p);  // 指针p的地址, 0x7ffe40054a68
    14 
    15     printf("sizeof(a) = %zu
    ", sizeof(a));   // 数组a的大小, 20
    16     printf("sizeof(p) = %zu
    ", sizeof(p));   // 指针的大小为8(64位系统)
    17 
    18     printf("
    ");
    19     
    20     p = b;
    21 
    22     printf("b = %p
    ", b);    // 0x7ffe40054a60, 数组b首元素的地址
    23     printf("p = %p
    ", p);    // 0x7ffe40054a60
    24     printf("&p = %p
    ", &p);  // 指针p的地址, 0x7ffe40054a68
    25 
    26     printf("sizeof(b) = %zu
    ", sizeof(b));  //数组的大小, 8
    27     printf("sizeof(p) = %zu
    ", sizeof(p));  //指针的大小为8(64位系统)
    28 
    29     // a = b;  // compile error, 数组名不能作为左值  
    30                // error: incompatible types when assigning to type ‘int[5]’ from type ‘int *’
    31 
    32     return 0;
    33 }
  • 相关阅读:
    【心得】软件团队Git工作流及Jira的基本知识和常见问题解释
    项目系统Netty的Channel和用户之间的关系绑定正确做法,以及Channel通道的安全性方案
    Redis中的事务(多命令)操作
    Redis中的订阅模式
    Redis中有序列表(ZSet)相关命令
    Redis散列(Hash)的相关命令
    输入输出流String间的转换
    linux 常用命令
    Gradle 使用
    c 学习笔记 0
  • 原文地址:https://www.cnblogs.com/shiwenjie/p/11853967.html
Copyright © 2011-2022 走看看