以下为个人学习笔记整理。参考书籍《C++ Primer Plus》

# 复合类型

# 指针、数组、指针算术

# 指针

  • 申明: typeName * pointerName
  • 赋值:
double* pn,pa;
char* pc;
double bubble = 3.2;
pn = &bubble; // 指向 bubble 的地址。
pc = new char; // 分配一个 char 大小的地址空间给 pc
pa = new double[30]; // 分配 30 个 double 大小的地址空间给 pa
  • 取值: *pointerName

  • 区分指针和指针所指内容:

    • 指针存储的是对象地址。
    • 通过 * 获取所指地址内的值。
  • 数组名:数组名视为数组第一个元素的地址。 int array[10];// array = &array[0]

  • 指针算术:

int array[10] = {1,2,3,4,5,6,7,8,9,1}
int* pt = array; // pt = &array[0]
pt += 1; // pt = &array[1]
int* pe = &array[9];
pe -= 1; // pe = &array[8]
int diff = pe - pt; // diff = &array[8] - &array[1] = 7
  • 数组动态联编和静态联编:

    • 静态联编,再编译时确定数组长度: int array[10];
    • 动态联编,在运行时确定数组长度: int* array = new [size]; delete[] array;//记得释放内存
  • 数组表示法和指针表示法:

    • array[0] == *array
    • array[3] == *(array + 3)
  • cout 对于 char* 类型的指针,会视作字符串进行输出,知道遇到 \0 时停止。

  • 结构名和结构指针:访问结构对象的成员属性时,有两种方式:

    • 如果操作的是结构名,可以用 . 来访问: structName.propty
    • 如果操作的是结构指针,可以用 -> 来访问: pointerStruct->propty
    • 或者通过指针获得结构体,再进行访问: (*pointerStruct).propty

# const 修饰符

  • const type* pointerName (常量指针)。const 修饰的指针不可以修改指向地址内存储的值。
int age = 24;
const int* pt = &age;
int money = 1;
pt = &money; // ok, change pointer
//*pt = 100; // no, change pointer val

C++ 禁止将 const 的地址赋给非 const 指针。

  • type* const pointerName (指针常量)。修饰的指针不可以修改指向,但可以修改所指地址。
int val = 10;
int* const pt = &val;
int val_1 = 100;
*pt = 100; // ok, change pointer val
pt = &val_1; // no, change pointer
  • const type* const pointerName (指向常量的常量指针)。所指地址不可变,所指地址内存储的值不可变。
int val = 10;
const int* const pt = &val; // 需要在初始化的时候赋值
int val_1 = 100;
*pt = 100; // no, change pointer val
pt = &val_1; // no, change pointer
  • const type& xtype const& x 等效,都表示 const 类型的引用,不可修改引用内的值。
  • const type* ptype const* p 等效,都表示 p 指向一个类型,并且该类型是 const 的,不可修改。
  • func() const 用作类函数时,表示该类对象需要为 const 才可以执行该函数。

扩展阅读:传送门

# 尽可能使用 const
  • 可以避免由于无意间修改数据而导致的编码错误。
  • const 修饰的变量,能够接受 const 和非 const 的数据。

# 数组的地址

  • 数组名被解释为其第一个元素的地址。

  • 对于数组名取地址操作将视为获得整个数组地址。

int array[2];
array + 1; //array next means 偏移一个 int 4 bytes
&array + 1; //next array means 偏移整个数组 8 bytes

string 类型的 = 赋值是深拷贝。而 char* 的拷贝只是变更指向地址。

# 函数传参

int main()
{
	int arr[10] = { 0 };
	int count = 10;
	cout << "arr args size = " << sizeof(arr) << endl;
	test_args(arr, count);
	return 0;
}
// 等价于 test_args (int* arr, int count) 
// 传递数组参数本质上就是传递数组第一个元素地址
void test_args(int arr[], int count) {
	cout << "「test_args」:arr args size = " << sizeof(arr) << endl;
}

image-20210221111430563

# 自动存储、静态存储、动态存储

# 自动存储

函数内部定义的变量使用「自动存储空间」。函数调用时,自动产生,结束后自动销毁。

  • 自动变量通常存储在「栈」中。拥有先进后出「LIFO」的特性,先创建的后销毁。

# 静态存储

整个程序执行过程中都存在的存储方式,存在于程序的整个生命周期。在函数外定义或者申明为 static 类型。

# 动态存储

一段可以由程序自己管控的「自由存储空间」—— 堆。通过 newdelete 来申请和释放。和自动存储、静态存储是分开的。

# 数组的替代品

  • vector:动态数组
vector<int> vi(10);
  • array:静态数组
array<int, 5> ai = {1,2,3,4,5};
更新于 阅读次数

请我[恰饭]~( ̄▽ ̄)~*

鑫酱(●'◡'●) 微信支付

微信支付

鑫酱(●'◡'●) 支付宝

支付宝