Chapter 3.数组和指针

来源:互联网 发布:洛瑞体测数据 编辑:程序博客网 时间:2024/06/06 03:11

数组和指针

        在C++中数组和指针对应于vector和iterator。区别在于vector长度可变(push_back操作),再者vector的capacity一般就比size大一些;而数组一经创建,就不能添加新元素。指针也可以像iterator一样用于数组。C++程序应尽量使用vector(相比数组更易调试)和iterator,一般只有在强调速度时才在类的内部使用数组和指针。

数组

数组定义和初始化

定义

        数组的维数必须为>=1的整型字面值常量、枚举常量、用常量表达式初始初始化的整型const对象,同时显式初始化的数组可以不用提供维数。
eg: int iArray[100];//100就是整形字面值常量int iArray[append];//这里的append见第二章,为枚举常量,值为2const size_t arraySize = 100;//此为第三种情况int iArray[arraySize+1];int iArray[] = {0,1,2};//显式初始化不提供维数

初始化

        如果没有显示提供元素初值,则遵从变量初始化原则。即在函数体外定义内置数组,元素全初始化为0;在函数体内定义则无初始化。数组元素为类类型时,不管在哪里都会调用默认构造函数进行初始化;如果没有默认构造函数,必须为类类型数组提供显式初始化。
        关于在函数体内内置数组无初始化的问题,如果维数大于列出的初始化的元素个数,剩余的就初始化为0
eg:char[20] = {0};//这里只列出了显式初始化的一个值0,因为维数20大于显式初始化的元素个数1,剩余就初始化为0

字符数组

eg:char ch[4] = {'C','+','+','\0'};//null terminator added explicitly//这两个字符数组等效char ch[4] = "C++";//null terminator added automatically

数组操作

eg:        int iArray1[] = {0,1,2};        size_t arraySize = sizeof(iArray1)/sizeof(*iArray1);        int iArray2[arraySize];        for(size_t index = 0; index != arraySize; ++index){                iArray2[index] = iArray1[index];        }

指针

        指针和迭代器的不同点在于指针用于指向单个对象,而迭代器只能用于容器内元素的访问。相同点在于都是提供对其所指对象的间接访问。

指针定义和初始化

定义

eg:vector<string> *pstring;//pstring can point to a vector<string>//其中 *pstring 是vector<string>类型,pstring是其地址

初始化或赋值

        指针可为下列四种类型的值:0值常量表达式、类型匹配的对象的地址、另一对象之后的下一地址、同类型的另一个有效指针
eg:        int *pi = 0;//字面值常量0        int *pi = NULL;//cstdlib头文件中定义的预处理器变量 NULL        const int c_iVal = 0;        int *pi = c_iVal;//整型const对象

void *指针

        可以保存任何类型对象的地址
eg:        double dVal = 3.14;        double *pd = &dVal;        void *pv = &dVal;        pv = pd;
        使用static_cast显式转换取出的void*指针
eg:double dVal = 3.14;void *pv = &dVal;double *p = static_cast<double*>(pv);

指针和引用的比较

        相同点:都可以间接访问另一个值
        不同点:引用总是指向某个对象,所以定义引用时一定要初始化;指针赋值修改是使指针与另一个对象关联,而引用赋值修改的是该引用所关联的对象的值
eg:int iVal = 1024;int &iRef = iVal;//引用总是要指向某个初始化的对象int *pi;//指针不一定要初始化(当然这里只是一个例子,最好是初始化指针变量即使是初始化为0)int *pi1 = 0;int *pi2 = pi1;//指针是关联另一对象int &iRef1 = iVal1;int &iRef2 = iVal2;iRef1 = iRef2;//引用是关联对象的值

指针算术操作

        只要两个指针指向同一数组或有一个指向该数组末端的下一单元,可对这两个指针做减法操作
eg://ptrdiff_t is signed int, define in cstddefptrdiff_t n = ip2 - ip1;//distance between the pointersint iArray[] = {0,1,2,3};int *ip = iArray;//ip point iArray[0]//first elementint lastElement = *(ip + sizeof(iArray)/sizeof(*iArray));//last element

用指针输出数组元素

eg:int iArray[] = {0,1,2,3,4,5};int iArraySize = sizeof(iArray)/sizeof(*iArray);for(int *pbegin = iArray, *pend = iArray +iArraySize; pbegin != pend; ++pbegin){cout << *pbegin << '\t';}

const与指针

eg:const int a;//const的是什么,const的是int,那么int不能修改int const a;//const的是什么,const的是a,那么a是什么,是int,那么int不能修改int const *a;//const的是什么,是*a,那么*a是什么,是int,那么*a不能修改,但是地址a能修改const int *a;//const的是什么,是int,那么int是什么,是*a,那么*a不能修改,但是地址a能修改int * const a;//const的是什么,是a,a是什么,是一个地址,那么a不能修改//因为const的是一个指针变量,所以叫做 const指针const int * const a;//const的是什么,是int,是a,那么int和a都不能修改

typedef与指针

eg:typedef string *pstr;//pstr是一个指向string类型的地址const pstr cstr;//const的是一个地址,即cstr相当于 string *const cstr;

C风格字符串

        永远不要忘记字符串后有个结束符'\0'
        头文件<cstring>中提供的标准函数
strlen(s);//返回s的长度,不包括结束符'\0'strcat(s1,s2);//s1←s1+s2strcmp(s1,s2);//0←s1==s2 、正数←s1>s2、负数←s1<s2strcpy(s1,s2);//s1←s2strncat(s1,s2,n);//s1←s1+s2[0,n]strncpy(s1,s2,n);//s1←s2[0,n]

创建动态数组

eg:string *pstr = new string[100];//用默认构造函数初始化为空int *piArray = new int[10]();//用()把int数组初始化为0

动态分配数组维数

size_t arrayLen;cin >> arrayLen;int *piArray = new int[arrayLen];for(int *q = p; q != p+arrayLen; ++q)//process arraydelete [] piArray;//const对象的动态数组const int *pciArray = new const int[100]();//可以new长度为0的数组char *cp = new char[0];//但是cp不能被解引用

新旧代码的兼容

        string类型提供了一个返回const char *的字符数组
eg:string str("Hello World!");const char *ch = str.c_str();

使用数组初始化vector对象

eg:const size_t arraySize = 6;int iArray[arraySize] = {1,2,3,4,5,6};vector<int> iVec(iArray,iArray+arraySize);

多维数组

eg://array of size 3, each element is an array of ints of size 4//3 row, 4 columnint iArray[3][4] = {{1,2,3},{4,5,6},{7,8,9}};

访问多维数组

eg:const size_t rowSize = 3;const size_t colSize = 4;for(size_t i = 0; i != rowSize; ++i){for(size_t j = 0; j != colSize; ++j){cout << iArray[i][j] << '\t';}cout << endl;}

指针和多维数组

eg:int iArray[3][4];int (*ip)[4] = iArray;//ip指向一个有4个int的数组