zoukankan      html  css  js  c++  java
  • C++自学笔记_数组和指针_《C++ Primer》

      

      1.数据定义中的类型可以是内置数据类型或者类类型,除引用数据类型之外,数组元素的类型可是是任何数据类型。没有所有元素都是引用数据类型的数组。

      2.数组的维数必须要用值大于等于1的表达式定义。此常量表达式只能包含整形字面值常量枚举常量或者用常量表达式初始化的const对象,否则在编译阶段不知道数组的维数,对于一个非const对象,只有运行时才能获得它的值。  

    const unsigned buf_size=512;
    int staff_size=27;
    char input_buffer[buf_size];    //ok:const variable
    double salaries[staff_size];    //error:non const variable

      3.关于初始化

      若没有显示提供元素初值,则数组会像普通变量一样初始化:

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

      · 函数体内定义的内置数组,其元素无初始化

      · 不管数组在哪里定义,如果其元素为类类型,则自动调用该类的默认构造函数进行初始化;

    string sa[10];        //元素初始化为空字符串
    int ia[10];              //元素初始化为0
    int main(){
        string sa2[10];  //元素初始化为空字符串
        int ia2[10];        //无初始化
        return 0;      
    }

      4.关于void*指针

      C++提供了一种特殊的指针void*,它可以用来保存任何一种数据类型对象的地址。

    double obj=3.14;
    double *pd=&obj;
    void *pv=&obj;  //ok:void* can hold the address value of any data pointer type
    pv=pd;

      void*指针只支持几种有限的操作:与另一个指针进行比较;向函数传递void*指针或者从函数返回void*指针;给另一个void*指针赋值。

      注意:不允许使用void*指针操纵它所指向的对象。

        5.之前没有完全理解什么叫做“引用一旦初始化以后就不能再指向另一个对象”这句话。其实是这样子:C++规定定义引用必须立即马上进行初始化,而当我再次给引用赋值时(曾经我以为这是把引用指向另一个对象..),实际上再次给引用赋值修改的是该引用所关联的对象的值,而并不是使引用与另一个对象关联(这也就是引用为什么在定义时即必须初始化的原因)。

      6.指向const对象的指针

    const double *cptr;

      这里的cptr是一个指向double型const对象的指针,也就是说,cptr本身并不是const,在定义它的时候不需要给他初始化。如果需要的话,也可以给cptr重新赋值,使其指向另一个const对象(此处要注意,可以把这种情况理解为:指向const对象的指针会自以为自己是指向const对象的指针,所以当再次给cptr赋值时,要是cptr指向的对象不再是const类型了,倒也不允许了呵呵)。

      把一个const对象的地址赋值给一个普通的、非const对象的指针也会导致编译时的错误。(所谓的指向const对象的指针也要具有const特性)。

    const double pi=3.14;
    double *ptr=π         //error
    const double *cptr=π  //ok

      允许把非const对象的地址赋值给指向const对象的指针。

    const double *cptr;
    double dval=3.14;
    cptr=&dval;       //ok:but can't change dval through cptr  

      cptr一旦定义,就不能通过cptr改变它所指向的值,但是并不是意味着cptr指向的非const对象就不可以修改了,可以通过普通的指向非const对象的指针进行修改。

      7.const指针

    int errNum=0;
    int *const curErr=&errNum;  //curErr is a constant pointer

      意味着curErr指针一旦初始化以后就再也不能指向别的对象。企图给任何const指针赋值的行为都会导致编译时的错误。但是,指针本事是const的事实并没有说明能否通过const指针修改它所指向的对象的值,能否修改完全取决于它所指的对象的类型。

      8.指向const对象的const指针

    const double pi=3.14;
    const double const *pi_ptr=π

      这么理解:首先,pi_ptr是个const指针,它又指向一个const对象。结果:既不允许修改pi_ptr所指向对象的值,也不允许修改pi_ptr的指向。

      9.创建动态数组

      动态数组并不是说数组的大小是可以变化的,而是指在编译的时候不必知道数组的长度,可以在运行的时候再确定数组的长度。并且,与数组变量不同的是,动态分配的数组将一直存在,直到程序显式释放它为之。
      :每一个程序在执行的时候都占用一块可用的内存空间,用于存放动态分配的对象,此内存空间称为程序的堆。C语言使用一对标准库函数malloc和free在堆中分配存储空间,C++语言使用new和delete表达式实现同样的功能。

      9.1 动态数组的定义

      动态分配数组时,只需指定类型和数组长度即可,用不着给数组命名,new表达式返回的是指向分配的内存空间的第一个元素的指针。

    int *pia=new int[10];

      9.2 初始化动态分配的数组

      动态分配数组时,如果数组元素师类类型,那么调用类的默认构造函数进行初始化;如果数组元素是内置数据类型,那么不进行初始化(和上面的函数内和函数外数组变量的初始化区别开来)。

    string *psa=new string[10];  //全部初始化为空字符串
    int *pia=new int[10];        //不进行初始化

       9.3 允许动态分配空数组

      之所以动态分配数组就是因为在编译时不知道数组的大小,可以编写如下代码:

    int n=get_size();
    int *p=new int[n];

    特别一提的是,n=0也是允许的。

      9.4 动态空间的释放

      必须要显式的将占用的内存空间释放,将之前占用的内存空间返回给堆,用delete[ ]实现。

    int *pia=new int[10];
    delete [] pia;

      10.新旧代码的兼容

      为了能够通过string实现对C风格字符串的初始化,string类提供了一个名为c_str()的成员函数。c_st()返回的是一个C风格字符串的首地址,这个C风格字符串的内容和string对象的内容相同。

      编写程序从标准输入设备读入字符串,并把该字符串存放在字符数组中。描述程序如何处理可变长的输入。

    int main(){ 
        string str;
        cin>>str;
        int len=str.size();
        char *p=new char[len+1];
        strcpy(p,str.c_str());return 0;
    }

       完了。

      

  • 相关阅读:
    浅谈c/c++中的指针问题
    谈谈八大排序算法问题
    隐藏在default construct后面的是什么
    浅谈编译过程和符号表重定位问题
    1.在VC编译器下面为什么每个头文件以及源文件都要包含“stdAfx.h”,那么stdAfx.h中到底存放了什么,用来做什么?
    成长从今天开始
    正则表达式
    安装RPM包或者安装源码包
    文档的压缩与打包
    文本编辑工具
  • 原文地址:https://www.cnblogs.com/Murcielago/p/4115751.html
Copyright © 2011-2022 走看看