文章目录
- 📚数组
- 🐇数组的概念
- 🐇数组的声明与使用
- 🐇数组的存储与初始化
- 🐇数组作为函数参数
- 🐇对象数组
 
- 📚指针
- 🐇内存空间的访问方式
- 🐇指针变量的声明
- 🐇指针运算
- 🐇指针的赋值
- 🐇指向常量的指针
- 🐇指针类型的常量
- 🐇用指针处理数组元素
- 🐇指针数组
- 🐇用指针作为函数参数
- 🐇指针类型的函数
- 🐇指向函数的指针
- 🐇对象指针
 
- 📚动态内存分配
- 🐇必要性
- 🐇new和delete
- 🐇动态创建多维数组
 
- 📚用vector创建数组对象
- 📚深拷贝与浅拷贝
- 📚字符串
📚数组
🐇数组的概念
- 数组是具有一定顺序关系的若干相同类型变量的集合体,组成数组的变量称为该数组的元素。
- 数组属于构造类型。
🐇数组的声明与使用
- 声明
  
- 使用 - 数组元素必须先声明,后使用。
- 只能逐个引用数组元素,而不能一次引用整个数组。例如:a[0]=a[5]+a[7]-a[2*3]、b[1][2]=a[2][3]/2。
- 下标值不得超过声明时所确定的上下界。
 
🐇数组的存储与初始化
- 🥕一维数组 - 一维数组的存储:数组元素在内存中顺次存放,它们的地址是连续的。
  
- 一维数组的初始化:可以在定义数组的同时赋给初值。
  
 
- 一维数组的存储:数组元素在内存中顺次存放,它们的地址是连续的。
- 🥕二维数组 - 二维数组的存储
  
- 二维数组的初始化
  
 
- 二维数组的存储
🐇数组作为函数参数
- 数组元素作实参,与单个变量一样。
- 数组名作参数,形、实参数都应是数组名(实质上是地址)。
- 类型要一样,传送的是数组首地址。对形参数组的改变会直接影响到实参数组。
🐇对象数组
- 声明:类名 数组名[元素个数];
- 访问:数组名[下标].成员名
- 初始化:数组中每一个元素对象被创建时,系统都会调用类构造函数初始化该对象。 - 通过初始化列表赋值。例:Point a[2]={Point(1,2),Point(3,4)};
- 如果没有为数组元素指定显式初始值,数组元素便使用默认值初始化(调用缺省构造函数)。
 
- 通过初始化列表赋值。例:
- 数组元素所属类的构造函数 - 不声明构造函数,则采用缺省构造函数。
- 各元素对象的初值要求为相同的值时,可以声明具有默认形参值的构造函数。
- 各元素对象的初值要求为不同的值时,需要声明带形参的构造函数。
- 当数组中每一个对象被删除时,系统都要调用一次析构函数。
 
📚指针
- C语言指针详解,30分钟玩转C语言指针
- 【动画教程】C语言指针动画演示
🐇内存空间的访问方式
- 通过变量名访问
- 通过地址访问
🐇指针变量的声明
- 概念
   - 指针:内存地址,用于间接访问内存单元。
- 指针变量:用于存放地址的变量。
 
🐇指针运算
- *称为指针运算符,是一个一元操作符,表示指针所指向的对象的值。
- &称为取地址运算符,也是一个一元操作符,是用来得到一个对象的地址。
- 指针变量的运算 -  指针变量的算术运算 
  - 这种运算的结果取决于指针指向的数据类型
  
 
- 这种运算的结果取决于指针指向的数据类型
-  指针变量的关系运算&赋值运算 
  
 
-  
🐇指针的赋值
- 指针变量的初始化
   - 注意事项 - 用变量地址作为初值时,该变量必须在指针初始化之前已声明过,且变量类型应与指针类型一致。
- 可以用一个已赋初值的指针去初始化另一个指针变量。
- 不要用一个内部 auto 变量去初始化 static 指针。@野指针详解
 
 
- 注意事项 
- 指针变量的赋值运算 - 指针名 = 地址- “地址”中存放的数据类型与指针类型必须相符。
- 向指针变量赋的值必须是地址常量或变量,不能是普通整数。但可以赋值为整数0,表示空指针。
- 指针的类型是它所指向变量的类型,而不是指针本身数据值的类型,任何一个指针本身的数据值都是unsigned long int型。
- 允许声明指向 void 类型的指针。该指针可以被赋予任何类型对象的地址。例: void *general;,不能声明void类型的变量。
 
 
🐇指向常量的指针
- 不能通过指针来改变所指对象的值,但指针本身可以改变,可以指向另外的对象。
  
🐇指针类型的常量
- 若声明指针常量,则指针本身的值不能被改变。
  
- const int * p1和- int * const p2的区别是什么❓- const int * p1声明了一个指向整型常量的指针p1,因此不能通过指针p1来改变它所指向的整型值;
- int * const p2声明了一个指针型常量,用于存放整型变量的地址,这个指针一旦初始化后,就不能被重新赋值了。
 
- 定义一个整型变量a,一个整型指针p,一个引用r,通过p把a的值改为10,通过r把a的值改为5❓void main() {int a;int *p = &a;int &r = a;*p = 10;r = 5; }
🐇用指针处理数组元素
- 声明与赋值 - int a[10], *pa; pa=&a[0];或- pa=a;
- 经过上述声明及赋值后: - pa就是- a[0],- (pa+1)就是- a[1],… ,- *(pa+i)就是- a[i]。
- a[i],- *(pa+i),- *(a+i),- pa[i]都是等效的。
- 不能写 a++,因为a是数组首地址是常量。
 
 
🐇指针数组
- 数组的元素是指针型
  
- 指针数组VS二维数组
  
  
🐇用指针作为函数参数
- 以地址方式传递数据,可以用来返回函数处理结果。
- 实参是数组名时形参可以是指针。
- 指向常量的指针做形参(不通过指针改变指针所指向对象的内容)#include<iostream> using namespace std; const int N = 6; void print(const int *p, int n); int main() {int array[N]; for (int i = 0; i < N; i++) cin>>array[i]; print(array, N); return 0; } void print(const int *p, int n) { cout << "{ " << *p; for (int i = 1; i < n; i++) cout << ", " << *(p+i); cout << " }" << endl; }
🐇指针类型的函数
- 若函数的返回值是地址,该函数就是指针类型的函数。
- 声明形式:存储类型 数据类型 *函数名()
- 注意 - 不要将非静态局部地址用作函数的返回值。
- 返回的指针要确保在主调函数中是有效、合法的地址。 - 例1:主函数中定义的数组,在子函数中对该数组元素进行某种操作后,返回其中一个元素的地址,这就是合法有效的地址
- 例2:在子函数中定义局部变量后将其地址返回给主函数,就是非法地址
- 例3:在子函数中通过动态内存分配new操作取得的内存地址返回给主函数是合法有效的,但是内存分配和释放不在同一级别,要注意不能忘记释放,避免内存泄漏
 
 
🐇指向函数的指针
- 声明形式:存储类型 数据类型 (*函数指针名)();
- 函数指针指向的是程序代码存储区。
- 典型用途——实现函数回调通过函数指针调用函数。 - 例如将函数的指针作为参数传递给一个函数,使得在处理相似事件的时候可以灵活的使用不同的方法。
- 调用者不关心谁是被调用者。它只需知道存在一个具有特定原型和限制条件的被调用函数。与函数名具有相同的作用。
 
🐇对象指针
- 声明形式:类名 *对象指针名;
- 通过指针访问对象成员:对象指针名->成员名,ptr->getx()相当于(*ptr).getx();
- this指针 - 隐含于每一个类的成员函数中的特殊指针。
- 明确地指出了成员函数当前所操作的数据所属的对象。 - 当通过一个对象调用成员函数时,系统先将该对象的地址赋给this指针,然后调用成员函数,成员函数对对象的数据成员进行操作时,就隐含使用了this指针。
 
 
- C++类和对象的使用之对象指针
📚动态内存分配
- 动态内存分配 (详解版)
🐇必要性
- 数组可以对大量的数据和对象进行有效管理,但很多情况下,程序运行之前并不能确切知道数组中元素的个数。
- 动态内存分配技术:保证程序在运行过程中按实际需要申请适量内存,且在使用结束后进行释放。
🐇new和delete
- 动态申请内存操作符new- new 数据类型T(初始化参数列表),- int * point = new int();。
- 功能:在程序执行期间,申请用于存放T类型变量/对象的内存空间,并依初值列表赋以初值。
- 结果值: - 成功:T类型的指针,指向新分配的内存;
- 失败:抛出异常。
 
 
- 释放内存操作符delete- delete 指针p
- 功能:释放指针p所指向的内存。p必须是new操作的返回值。
- 注意:New分配的内存必须用delete加以释放。
 
🐇动态创建多维数组
- new 类型名T[第1维长度][第2维长度]…;
- 如果内存申请成功,new运算返回一个指向新分配内存首地址的指针,是一个T类型的数组,数组元素的个数为除最左边一维外各维下标表达式的乘积。
  
📚用vector创建数组对象
- 使用vector创建数组对象
- 为什么需要vector? - 将动态数组封装,自动创建和删除数组下标越界检查
 
- vector动态数组对象的定义 - vector<元素类型> 数组对象名(数组长度);
- 例:vector<int> arr(5),建立大小为5的int数组
 
- 对数组元素的引用 - 与普通数组具有相同形式:数组对象名 [ 下标表达式 ]
- 但vector数组对象名不表示数组首地址
 
- 与普通数组具有相同形式:
- 获得数组长度 - 用size函数
- 数组对象名.size()
 
📚深拷贝与浅拷贝
- 浅拷贝:实现对象间数据元素的一一对应复制。
- 深拷贝:当被复制的对象数据成员是指针类型时,不是复制该指针成员本身,而是将指针所指对象进行复制。
📚字符串
- C++中的String的常用函数用法总结
 