• 数组进阶提高


    1.一维数组

    1.1概念:

    1. 元素类型角度:数组是相同类型的变量的有序集合
    2. 内存角度:连续的一大片内存空间

     

    在讨论多维数组之前,我们还需要学习很多关于一维数组的知识。首先让我们学习一个概念。

    1.2 数组名:

    考虑下面这些声明:

    int a;

    int b[10];

    我们把a称作标量,因为它是个单一的值,这个变量是的类型是一个整数。我们把b称作数组,因为它是一些值的集合。下标和数名一起使用,用于标识该集合中某个特定的值。例如,b[0]表示数组b的第1个值,b[4]表示第5个值。每个值都是一个特定的标量。

    那么问题是b的类型是什么?它所表示的又是什么?一个合乎逻辑的答案是它表示整个数组,但事实并非如此。在C中,在几乎所有数组名的表达式中,数组名的值是一个指针常量,也就是数组第一个元素的地址。它的类型取决于数组元素的类型:如果他们是int类型,那么数组名的类型就是“指向int的常量指针”;如果它们是其他类型,那么数组名的类型也就是“指向其他类型的常量指针”。

    请问:数组首地址指针和数组名是等价的吗?

    答案是否定的。数组名在表达式中使用的时候,编译器才会产生一个指针常量。那么数组在什么情况下不能作为指针常量呢?在以下两种场景下:除了这俩种,其余都等价

    1. 当数组名作为sizeof操作符的操作数的时候,此时sizeof返回的是整个数组的长度,而不是指针数组指针的长度。
    2. 当数组名作为&操作符的操作数的时候,此时返回的是一个指向数组的指针,而不是指向某个数组元素的指针常量。

     

    int arr[10];

    //arr = NULL; //arr作为指针常量,不可修改

    int *p = arr; //此时arr作为指针常量来使用

    printf("sizeof(arr):%d\n", sizeof(arr)); //此时sizeof结果为整个数组的长度

    printf("&arr type is %s\n", typeid(&arr).name()); //int(*)[10]而不是int*

    1.3 下标引用

    int arr[] = { 1, 2, 3, 4, 5, 6 };

    *(arr + 3) ,这个表达式是什么意思呢?

    首先,我们说数组在表达式中是一个指向整型的指针,所以此表达式表示arr指针向后移动了3个元素的长度。然后通过间接访问操作符从这个新地址开始获取这个位置的值。这个和下标的引用的执行过程完全相同。所以如下表达式是等同的,且下标可以为负数。

    *(arr + 3)

    arr[3]

    问题1:数组下标可否为负值?

    可以的,相当于解引用

     

    问题2:请阅读如下代码,说出结果:

    int arr[] = { 5, 3, 6, 8, 2, 9 };

    int *p = arr + 2;

    printf("*p = %d\n", *p);

    printf("*p = %d\n", p[-1]);

    那么是用下标还是指针来操作数组呢?对于大部分人而言,下标的可读性会强一些。

  • 相关阅读:
    机器学习笔记 - 用于3D点云数据分类的Point Net的训练
    ajax(Springmvc实现和注册提示效果)
    图片翻译软件哪个好用?这些软件值得收藏
    加速度速度位移的计算
    Day741.Redis消息队列 -Redis 核心技术与实战
    Go语言快速入门篇(二):变量
    Spring的组件扫描配置
    Scala学习记录1--简介与环境配置
    Google Universal Image Embedding比赛丨北大第一名方案总结
    WPF中的依赖属性
  • 原文地址:https://blog.csdn.net/weixin_46098612/article/details/125550827