C++primer 第四章学习:数组和指针

  1. C++ 语言提供了两种类似于 vector 和迭代器类型的低级复合类型——数组和指针。

  2. 数组定义中的类型名可以是内置数据类型或类类型;除引用之外,数组元素的类型还可以是任意的复合类型。没有所有元素都是引用的数组。

  3. 显式初始化数组元素:int ia[array_size] = {0, 1, 2};

  4. 如果没有显式提供元素初值,则数组元素会像普通变量一样初始化

    • 在函数体外定义的内置数组,其元素均初始化为 0
    • 在函数体内定义的内置数组,其元素无初始化
    • 不管数组在哪里定义,如果其元素为类类型,则自动调用该类的默认构造函数进行初始化;如果该类没有默认构造函
      数,则必须为该数组的元素提供显式初始化。
  5. 字符数组既可以用一组由花括号括起来、逗号隔开的字符字面值进行初始化,也可以用一个字符串字面值进行初始化。

    char ca1[] = {'C', '+', '+'}; // no null 
    char ca2[] = {'C', '+', '+', '\0'}; // explicit null 
    char ca3[] = "C++"; // null terminator added automatically
    
  6. 指针是指向某种类型对象的复合数据类型,是用于数组的迭代器:指向数组中的一个元素。指针保存的是另一个对象的地址:

    string s("hello world"); 
    string *sp = &s; // sp holds the address of s 
  7. 现代 C++程序采用 vector类型和迭代器取代一般的数组、采用 string 类型取代 C 风格字符串。

  8. 如果必须分开定义指针和其所指向的对象,则将指针初始化为 0。因为编译器可检测出 0 值的指针,程序可判断该指针并未指向一个对象。

  9. C++ 提供了一种特殊的指针类型 void*,它可以保存任何类型对象的地址。void* 表明该指针与一地址值相关,但不清楚存储在此地址上的对象的类型。不允许使用 void* 指针操纵它所指向的对象。
  10. C 语言中继承下来的预处理器变量 NULL,该变量在 cstdlib 头文件中定义,其值为 0。
  11. C++ 语言中,指针和数组密切相关。特别是在表达式中使用数组名时,该名字会自动转换为指向数组第一个元素的指针:

    int ia[] = {0,2,4,6,8}; 
    int *ip = ia; // ip points to ia[0] 
  12. 两个指针减法操作的结果是标准库类型(library type)ptrdiff_t的数据。与 size_t 类型一样,ptrdiff_t 也是一种与机器相关的类型,在 cstddef 头文件中定义。size_t 是 unsigned 类型,而 ptrdiff_t 则是 signed 整型。

  13. C++ 语言强制要求指向 const 对象的指针也必须具有 const 特性:

    const double pi = 3.14; 
    double *ptr = π // error: ptr is a plain pointer 
    const double *cptr = π // ok: cptr is a pointer toconst
  14. 允许把非 const 对象的地址赋给指向 const 对象的指针。

  15. 假设给出以下语句:
    typedef string *pstring;
    const pstring cstr;
    声明 const pstring 时,const 修饰的是 pstring 的类型,这是一个指针。因此,该声明语句应该是把 cstr 定义为指向 string 类型对象的 const 指针,这个定义等价于:
    // cstr is a const pointer to string
    string *const cstr; // equivalent to const pstring cstr

  16. C++ 语言通过(const)char*类型的指针来操纵 C 风格字符串。

    const char *cp = "some value"; 
    while (*cp) { 
    // do something to *cp 
    ++cp; 
    } 

17 . cstring 是 string.h 头文件的 C++ 版本,而 string.h 则是 C 语言提供的标准库。

18 . 使用标准库类型 string,除了增强安全性外,效率也提高了,因此应该尽量避免使用 C 风格字符串。

19 . 每一个程序在执行时都占用一块可用的内存空间,用于存放动态分配的对象,此内存空间称为程序的自由存储区或堆。C 语言程序使用一对标准库函数malloc 和free 在自由存储区中分配存储空间,而 C++ 语言则使用 new和 delete表达式实现相同的功能。

20 . 动态分配数组时,如果数组元素具有类类型,将使用该类的默认构造函数实初始化;如果数组元素是内置类型,则无初始化:

string *psa = new string[10]; // array of 10 empty strings 
int *pia = new int[10]; // array of 10 uninitialized ints
int *pia2 = new int[10] (); // array of 10 uninitialized ints 

21 . 如果我们在自由存储区中创建的数组存储了内置类型的 const 对象,则必须为这个数组提供初始化:

// ok: value-initialized const array 
const int *pci_ok = new const int[100](); 

22 . 之所以要动态分配数组,往往是由于编译时并不知道数组的长度:

size_t n = get_size(); // get_size returns number of elements needed 
int* p = new int[n]; 
for (int* q = p; q != p + n; ++q) 
 /* process the array */ ;

23 .动态分配的内存最后必须进行释放,否则,内存最终将会逐渐耗尽。如果不再需要使用动态创建的数组,程序员必须显式地将其占用的存储空间返还给程序的自由存储区。C++ 语言为指针提供 delete [] 表达式释放指针所指向的数组空间:

delete [] pia;

24 .

int ia[3][4] = { /* 3 elements, each element is an array of size 4*/ 
{0, 1, 2, 3} , /* initializers for row indexed by 0*/ 
{4, 5, 6, 7} , /* initializers for row indexed by 1*/ 
{8, 9, 10, 11} /* initializers for row indexed by 2*/ 

// explicitly initialize only element 0 in each row 
int ia[3][4] = {{ 0 } , { 4 } , { 8 } }; 
};

25 .

int ia[3][4]; // array of size 3, each element is an array of 
ints of size 4 
int (*ip)[4] = ia; // ip points to an array of 4 ints 
ip = &ia[2]; // ia[2] is an array of 4 ints

int *ip[4]; // array of pointers to int 
int (*ip)[4]; // pointer to an array of 4 ints 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值