• C++ PRIMER 学习笔记 第四章


    第4章 数组和指针

      C++程序应尽量使用vector 和 迭代器类型,避免使用低级的数组和指针

      4.1 数组

      数组是由 类型名、标识符 维数 组成的复合数据类型,类型名规定了存放在数组中的元素的类型维数 指定 数组中包含的元素个数,数组的维数必须用值大于等于1的常量表达式定义,此常量表达式只能包含 整形字面值常量枚举常量 或者用常量表达式初始化的 整形const对象

      在函数体外定义的内置数组,其元素均初始化为0在函数体内 定义的内置数组,其元素无初始化

      如果指定了数组维数,那么初始化列表提供的元素个数不能超过维数值,如果维数大于列出的元素初值个数,则只初始化前面的数组元素,剩下的其他元素,若是内置类型则初始化为0,若是类类型则调用该类的默认构造函数进行初始化

      不允许数组直接复制和赋值,数组下标的正确类型是 size_t

      4.2 指针

      指针 是指向某种类型对象的复合数据类型,是用于数组的迭代器,指向数组中的一个元素(保存元素的地址)对指针进行解引用操作,可获得该指针所指向对象的值

      指针用于指向对象,具体来说,指针保存的是另一个对象的地址,取地址操作符&只能用于左值,因为 有当变量用作左值时 ,才能取其地址,理解指针声明语句时,请从右向左阅读,将符号 * 紧贴着指针变量名放置不易引起误解

       一个有效的指针必然是以下三种状态之一:保存一个特定对象的地址指向某个对象后面的另一个对象,或者是 0值

      除非所指向的对象已经存在,否则不要先定义指针,如果必须分开定义指针和其所指向的对象,则将指针初始化为0(字面值0,或者在编译时可获得0值的const量,或者C++语言从C语言中继承下来的预处理变量 NULL,该变量在cstdlib头文件中定义,其值为0)

       C++提供了一种特殊的指针类型void*,它可以保存任何类型对象的地址,void*指针支持的操作:与另一个指针进行比较,向函数传递void*指针或从函数返回void*指针,给另一个void*指针赋值

      解引用操作符,返回指定对象的左值 ,如果对左操作数进行解引用,则修改的是指针所指对象的值,如果没有使用解引用操作,则修改的是指针本身的值

      在表达式中使用数组名时,该名字会自动转换为指向该数组第一个元素的指针,如果希望使指针指向数组中的一个元素,可使用下标操作符给某个元素定位,然后用取地址操作符&获取该元素的存储地址 

      指针的算术操作:指针上加上或减去一个整形数值,两个指针做减法

      在指针上加上一个整形数值,其结果仍然是指针,允许在这个结果上直接进行解引用操作,而不必先把它赋给一个新指针,两个指针减法操作的结果是标准库类型ptrdiff_t的数据,也是一种与机器相关的类型,在cstddef头文件中定义,是signed整形

      在使用下标访问数组时,实际上是对指向数组元素的指针做下标操作

      指针加数组长度即可以计算出数组的超出末端指针,C++允许计算数组或对象的超出末端的地址,但不允许对此地址进行解引用操作

      允许把非const对象的地址赋给指向const对象的指针,不能用指向const对象的指针修改基础对象,然而如果该指针指向的是一个非const对象,可用其他方法修改其所指向的对象,指向const的指针常用作函数的形参,确保传递给函数的实际对象在函数中不因为形参而被修改

      与任何const量一样,const指针也必须在定义时初始化,任何企图给const指针赋值的行为即使给指针赋回同样的值,都会导致编译时的错误

      指向const对象的const指针,既不能修改指针所指向对象的值,也不允许修改该指针的指向

      4.3 C风格字符串

      4.4多维数组

      C++中没有多维数组,通常所指的多维数组其实就是 数组的数组

    //array of size 3, each element is an array of ints of size 4
    int ia[3][4];

      如果 数组的元素 又是 数组,则称为二维数组,其每一维对应一个下标,第一维称为行,第二维则称为列,C++并未限制可用的下标个数,也就是说,可以定义元素是数组(其元素又是数组,以此类推)的数组

      为了对多维数组进行索引,每一维都需要一个下标,当需要访问数组中的特定元素时,必须提供其行下标和列下标,行下标指出需要哪个内部数组,列下标则选取该内部数组的指定元素

      使用 多维数组名 时,实际上将其自动转换为指向该数组第一个元素的指针

    #include<stdio.h>
    int main()
    {
        int arr[2][3] = { 1,2,3, 4,5,6 };       
        int(*q)[3] = &arr[0]; 
        //int(*q)[3] = arr;    //arr 自动转换为,指向,该数组第一个元素( arr[0] )的地址
                               //arr[0] 是一维数组名,一维数组元素的首地址,*arr[0]即arr[0][0] 元素为1
                               //int *p = arr[0]; p++; printf("%d",*p);
        q++; 
        printf("%d",**q);    
        return 0;
    }
    #include<stdio.h>
    int main()
    {
        int arr[2][3] = { 1,2,3, 4,5,6 };        
        typedef int int_arr[3]; //定义类型为int[3]的新的类型为int_arr
        int_arr *q = &arr[0]; // int(*q)[3]
        //遍历二维数组 arr
        for( ; q != arr+2; ++q ){  //q++         q  保存的是行的地址
            for( int* p=*q; p != *q+3; ++p ){ //*q  解引用是行的地址
                printf("%d ", *p );
            }
            printf("\n");
        }    
        return 0;
    }
    #include<stdio.h>
    int main()
    {
        int arr[2][3] = { 1,2,3, 4,5,6 };       
        int(*q)[3] = &arr[0];    //取arr第一个元素的地址 
                                 //int(*q)[3] = ( int(*)[3] ) arr[0];    
        int*p = *q;              //一维指针的指向,即arr第一个元素的地址
                                 //int* p = arr[0];
        //打印结果一样
        printf("%p\n",arr[0]);   //第一个元素的地址
        printf("%p\n",&arr[0]);  //取第一个元素的地址
        printf("%p\n",p);        //一维指针的指向
        printf("%p\n",q);        //行指针的指向
        
        return 0;
    }
  • 相关阅读:
    Android 编译命令 make j8 2>&1 | tee build.log 解释
    Linux时间函数之gettimeofday()函数之使用方法
    转:RSA算法原理说明
    转: 各个密码算法的实现(未验证)
    转:修改Android签名证书keystore的密码、别名alias以及别名密码
    转:Eclipse ADT的Custom debug keystore所需证书规格
    转:如何转换Android打包用jks格式keystore证书为Air用pkcs12格式p12证书
    转: 关于流量控制与令牌桶介绍
    转:sublime2 官方网址
    转:Mac OS X下Sublime Text (V2.0.1)破解
  • 原文地址:https://www.cnblogs.com/GoldenEllipsis/p/16571439.html
Copyright © 2020-2023  润新知