0%

C++ Primer学习笔记(二)

指向指针的指针

1
2
3
int ival = 1024;
int *pi = &ival; // pi points to an int
int **ppi = π // ppi points to a pointer to an int

截屏2021-06-02 上午10.14.16

指向指针的引用

1
2
3
4
5
int i = 42;
int *p;//p isa pointer to int
int *&r = p;// r is a reference to the pointer p
r = &i; // r refers to a pointer; assigning &i to r makes p point to i
*r = 0; // dereferencing r yields i, the object to which p points; changes i to 0
  • 如何理解int *&r = p;

    从右往左看,最靠近r的是&,说明r是一个引用,然后是*,说明r指向指针,最后是int,说明r是一个指向int类型指针的引用。

Exercises Section 2.3.3
Exercise 2.25:
Determine the types and values of each of the following variables.

(a) int* ip, &r = ip;

(b) int i, *ip = 0;

(c) int* ip, ip2;

(a) ip:int类型的指针,r:指向int类型指针的引用

(b) i:int类型的变量,ip:int类型的指针

(c)ip:int类型的指针,ip2:int类型的变量

常量限定符(const)

  • const修饰的对象不可修改
1
2
const int bufSize = 512; // input buffer size
bufSize = 512; // error: attempt to write to const object
  • const修饰的对象必须初始化
1
2
3
const int i = get_size(); // ok: initialized at run time
const int j = 42; // ok: initialized at compile time
const int k; // error: k is uninitialized const
  • 在多个文件中使用const修饰的对象
1
2
3
4
// file_1.cc defines and initializes a const that is accessible to other files 
extern const int bufSize = fcn();
// file_1.h
extern const int bufSize; // same bufSize as defined in file_1.cc

Exercises Section 2.4
Exercise 2.26:
Which of the following are legal? For those that are illegal,

explain why.

(a) const int buf;

(b) int cnt = 0;

(c) const int sz = cnt;

(d) ++cnt; ++sz;

(a):❌ (d):++cnt;(✅)++sz;(❌)

常量引用

1
2
3
4
const int ci = 1024; 
const int &r1 = ci; // ok: both reference and underlying object are const
r1 = 42; // error: r1 is a reference to const
int &r2 = ci; // error: non const reference to a const object
  • 常量引用不可修改值
  • 非常量引用不可指向常量对象
1
2
3
4
int i = 42;
const int &r1 = i; // we can bind a const int& to a plain int object const int &r2 = 42; // ok: r1 is a reference to const
const int &r3 = r1 * 2; // ok: r3 is a reference to const
int &r4 = r * 2; // error: r4 is a plain, non const reference

常量引用可以指向 非常量对象字面量通用表达式

1
2
double dval = 3.14; 
const int &ri = dval;
  • 常量引用会自动强制类型转化
1
2
const int temp = dval; // create a temporary const int from the double 
const int &ri = temp; // bind ri to that temporary

常量指针(pointer to const)

指向常量的指针,指针地址可以修改,但地址存放的值不可以修改

1
2
3
4
const double pi = 3.14; // pi is const; its value may not be changed
double *ptr = π // error: ptr is a plain pointer
const double *cptr = π // ok: cptr may point to a double that is const
*cptr = 42; // error: cannot assign to *cptr
  • 指向常量的指针地址存放的值不可修改
1
2
double dval = 3.14; // dval is a double; its value can be changed
cptr = &dval; // ok: but can't change dval through cptr
  • 指向常量的指针可以指向非常量对象

指针常量(const Pointers)

1
2
3
4
int errNumb = 0;
int *const curErr = &errNumb; // curErr will always point to errNumb const
double pi = 3.14159;
const double *const pip = π // pip is a const pointer to a const object

从右往左看:curErrconst修饰,不可修改

1
2
3
4
*pip = 2.72; // error: pip is a pointer to const
// if the object to which curErr points (i.e., errNumb) is nonzero
if (*curErr) {
*curErr = 0; // ok: reset the value of the object to which curErr is bound }

Exercises Section 2.4.2
Exercise 2.27:
Which of the following initializations are legal? Explain why.

(a) int i = -1, &r = 0;
(b) int const p2 = &i2;
(c) const int i = -1, &r = 0;
(d) const int *const p3 = &i2;
*
(e)** const int *p1 = &i2;
(f) const int &const r2;
(g) const int i2 = i, &r = i;

(a)❌ 引用必须指向一个对象

(f) ❌常量必须初始化

Exercise 2.28: Explain the following definitions. Identify any that are illegal.

(a) int i, *const cp;
(b) int *p1, *const p2;

(c) const int ic, &r = ic;

(d) const int *const p3;

(e) const int *p;

原因:常量初始化没有赋值

常量表达式

常量表达式是指能够在编译时确定值

1
2
3
4
const int max_files = 20; // max_files is a constant expression
const int limit = max_files + 1; // limit is a constant expression
int staff_size = 27; // staff_size is not a constant expression
const int sz = get_size(); // sz is not a constant expression

尽管sz是一个常量,但是它的值只有在运行时才能确定,因此sz不是一个常量表达式

constexpr

1
2
3
constexpr int mf = 20; // 20 is a constant expression 
constexpr int limit = mf + 1; // mf + 1 is a constant expression
constexpr int sz = size(); // ok only if size is a constexpr function

constexpr避免了出现上述sz的情况

1
2
const int *p = nullptr; // p is a pointer to a const int 
constexpr int *q = nullptr; // q is a const pointer to int

constexpr是top-level const,即指针本身是常量(low-level const是指针指向常量对象)

1
2
3
4
5
6
constexpr int *np = nullptr; // np is a constant pointer to int that is null
int j = 0;
constexpr int i = 42; // type of i is const int
// i and j must be defined outside any function
constexpr const int *p = &i; // p is a constant pointer to the const int i
constexpr int *p1 = &j; // p1 is a constant pointer to the int j