11.1之前 | 1—12 指针之前 |
---|---|
11.1 | 13-20 拷贝构造函数之前 |
- 简单赋值
int a(868);int a= 868;//a(868) == a=868double a,s,d,f = 1.25;//可以同时定义多个同类型变量,且可给变量赋值
- 复合赋值
x+=y;//x = x+y;
//+= -= *= /= %= => x = x _ y
- 赋值表达式总是先将右边的操作数或者表达式进行计算后,将计算结果赋给左边的变量。
x = y+z ; // 先y+z ,再将和的结果赋给x
- 在一个表达式中当连续使用多个赋值运算符时,运算顺序为从右向左。
x=y=z=0;//先z=0; 再将z的值赋给y; 最后将y的值赋给x
二、自增自减预算符
++i; --i;//先运算+1/-1 再参加运算
i++; i--;//先参加运算 再+1/-1
-------------------------------------
int i , j ;
i = 2 ; j = 4;
cout << i++ << "" <<--j <<"";
cout << i << "" << j <<endl;
//输出结果为
//2 3 => i先参加运算输出,再自加 ,j先自减,再参加运算输出
//3 3
-------------------------------------
int x = 5 , y = 10;
x = --y-5;
cout << x << "" << y << endl;
//输出结果为
//4 9 =>--y-5 => (--y)-5 => 9 - 5 = 4
三、关系运算符
- 大于> 小于< 大于等于>= 小于等于<= 等于== 不等于!=
- 当关系式成立时为1,反之为0
int a , b(1) , c(-1) , d(1);
a = ((b+c)>=d);
cout << a << "" <<endl;
//输出结果为
//0 => 先执行b+c=0 ,再执行(b+c)>=d,由于0 >= 1不满足,所以a = 0。
- 注意a == b 和 a = b,在手写代码时别搞混!!
四、逻辑运算符
- 与&& 仅左右两边同时为1时,为1 。
- 或|| 左右两边至少有一个为1,则为1。
- 非! 取反,右边为1,得到0,反之亦然。
- 一个逻辑表达式中有可列个&& 和 || ,从左到右进行运算。
int x = 0 , y = 1 ,z;
z = x++ && y--;
cout << x << "" << y << "" << z <<endl;
//输出结果为
//错误:1 0 1 => (x++) , x=1 => 1 && y=1 => z = 1 => y-- , y = 0
//正确:1 1 0 => x先参与计算再自加1 => 因为x = 0 &&的结果肯定为0,所以y--不运行 =>x = 1 , y = 1 , z = 0
- 逻辑表达式运算时,若已能判断表达式值,整个过程将提前结束,这种现象称为 逻辑短路,如上例子。
五、条件运算符
- e1 ? e2 : e3; e1满足执行e2,e1不满足执行e3。
六、 逗号运算符
- 形式: e 1 , e 2 , e 3 . . . , e n e_1,e_2,e_3...,e_n e1,e2,e3...,en
- x = ( e 1 , e 2 , e 3 . . . , e n ) x = (e_1,e_2,e_3...,e_n) x=(e1,e2,e3...,en),对于所有的 e i e_i ei表达式从左到右开始计算直到 e n e_n en,最后将 e n e_n en的值赋给x。
int a, b = 2,c = 5;
a = (b++, c -= 3 , b+=c , b-c);
cout <<a <<"" <<b<<""<<c <<"" <<endl;
//输出结果为
//3 5 2 => b++ , b=3 => c=c-3 , c=2 => b=b+c , b=5 => b-c=3 , a=3
七、 求字节运算符
- sizeof(e),求得e所占用字节数。
- double 求出为8 ; float int 求出为4 ;double*float = double
八、if语句
九、switch语句
switch(表达式){case a1: 语句块1 (break;)...case an: 语句块n (break;)(default: 语句块 (break;))
}
//a1 an 为不同得常量
//default 语句可有可无,可以放在任意位置,一般放最后
- switch语句中,如果case语句中没有break,则继续向下执行后一个case语句,直到遇到break或者switch语句结束。
十、三大循环 for while do-while
-
for (e1; e2; e3) {
// 循环体
} -
其中e1为循环变量赋值 ,e2判断是否循环 ,e3修改循环条件中得变量 ,e2可以为空。
-
e1 → e2(如果为真) → 循环体 → e3
重复:e2(如果为真) → 循环体 → e3
一直到 e2 为假,退出循环。 -
while(表达式) 当表达式不满足或者循环体中遇到break,停止循环。
-
do
循环体
while(表达式) 先执行循环体,后判断表达式是否非0,若非0继续执行循环体,直至表达式为0。 -
do-while循环至少循环一次。
十一、两大跳转
- break;
- switch语句下,跳出case,结束当前循环。
- 多重循环下,跳出当前循环体,不跳出外套循环。
- continue;
- 退出当前循环,下一次该循环还是循环。
十二、数组
- 二维数组
int a[2][3] = {{1,2,3},{4,5, 6}};
int a[2][3] = {1,2,3,4,5,6};
//上面两个等价
//如果{}里面的元素个数 < m*n,则多出来的空间均为0
十三、 指针
//形式:类型名 *标识符
DLNode *p;
int q , *p;
p = &q; //&取变量地址的运算符,所以p指向的是q的地址
*p = 6;//*取指针变量 所指内容的原算符,即取p指向地址的内容,即q的内容,q的值为6,所以*p的内容是6
十四、 函数调用
- 传值调用int a
func.被调用时,为形参分配空间 同时 将实参copy给形参,在func.中执行时只访问形参 而与实参无关,故而形参变化不影响实参的值。
e.g.
main()中调用void swap(int a,int b);的语句为swap(x,y);
在main中调用前调用后的xy值不变,他是实参;
在swap中的输出就是a = y b = x因为swap了,ab是形参 - 传地址调用int *a
func.被调用时,把实参地址copy给形参的指针,这样在函数执行时改变了形参内容指针的同时,也更改了实参所指的内容,故而通过该边形参所指变量而改变了实参。
e.g.
main()中调用**void swap(int a,int b);的语句为swap(&x,&y);
在main中调用前调用后的xy值变,即形参的改变会导致实参的改变。 - 传引用调用int &a
使用引用作为函数参数,在形参面前加&,与传地址作用相似,在改变形参的同时也改变了实参的值。
e.g.
main()中调用void swap(int &a,int &b);的语句为swap(x,y);
在main中调用前调用后的xy值变,即形参的改变会导致实参的改变。
十五、作用域与生存期
作用域是关于变量能在哪些地方使用,访问的范围
生存期是关于变量何时分配和释放,即变量在内存中的存在时长
作用域:块作用域,从块中对某变量的定义开始,直至块对应的} 为止。
生存期:静态变量static,与整个程序的作用期相同。
作用域符 | 声明位置 | 生存期 |
---|---|---|
局部变量 | 函数体内 程序块内 | 函数或块被执行时存在 函数调用或块结束时释放 |
内部静态 | 函数体内 | 初始化一次,直至程序结束 |
外部静态 | 函数体外 | 从声明处开始,直到所在源程序文件结束 |
全局变量 | 函数体外 | 从声明处开始,一直到程序结束 |
局部变量:局部变量是在函数或代码块中声明的变量,只在所在的代码块内有效(作用域),当函数调用或代码块结束时会被释放(生存期)。
#include <iostream>
void exampleFunction() {int localVar = 5; // 局部变量std::cout << "局部变量 localVar = " << localVar << std::endl;
} // localVar 的作用域到这里结束,生存期也随之结束int main() {exampleFunction();// std::cout << localVar; // 错误,localVar 超出了作用域return 0;
}
内部静态:内部静态变量是在函数内部声明的 static 变量,作用域仍在函数内,但生存期是整个程序运行期间,即函数每次调用时,该变量不会被重新分配和释放。
#include <iostream>
void exampleFunction() {static int staticVar = 0; // 内部静态变量,只初始化一次staticVar++;std::cout << "内部静态变量 staticVar = " << staticVar << std::endl;
}int main() {exampleFunction(); // 输出 1exampleFunction(); // 输出 2return 0;
}
外部静态:外部静态变量在文件作用域声明,但只在该文件中可见。它的作用域从声明位置到文件末尾,生存期为整个程序运行期间。
#include <iostream>static int fileStaticVar = 10; // 外部静态变量,只在当前文件中可见void exampleFunction() {std::cout << "外部静态变量 fileStaticVar = " << fileStaticVar << std::endl;
}int main() {exampleFunction(); // 输出 10return 0;
}
全局变量:全局变量在文件作用域中声明,可以在程序的其他文件中【和外部静态变量区别】 通过 extern 声明来访问。它的生存期是整个程序运行期间,作用域从声明位置到程序结束。
#include <iostream>int globalVar = 100; // 全局变量void exampleFunction() {std::cout << "全局变量 globalVar = " << globalVar << std::endl;
}int main() {exampleFunction(); // 输出 100return 0;
}
十六、作用域分辨符 :: 😃
作用域分辨符 的目的是引用全局变量 =>【::value和value不同!!】
#include <iostream>int value = 42; // 全局变量void displayValues() {int value = 10; // 局部变量,与全局变量同名std::cout << "局部变量 value = " << value << std::endl;std::cout << "全局变量 value = " << ::value << std::endl; // 使用作用域分辨符访问全局变量
}int main() {displayValues();return 0;
}
//输出结果
局部变量 value = 10
全局变量 value = 42
十七、类的访问控制
class 类名{
public: 公有成员或公有成员函数
private: 私有成员或私有成员函数
protected: 保护成员或者保护成员函数
};
类的访问控制 | 访问权限 |
---|---|
public | 公有成员变量,可以在类外直接访问 |
private | 私有成员变量,类外无法直接访问 |
protected | 护成员变量,类外无法直接访问,派生类可访问 |
//AI生成
#include <iostream>
using namespace std;class Example {
public:int publicVar; // 公有成员变量,可以在类外直接访问Example(int pub, int pri, int prot) : publicVar(pub), privateVar(pri), protectedVar(prot) {}void publicFunction() { // 公有成员函数,可以在类外直接访问cout << "这是一个公有成员函数。" << endl;cout << "访问私有成员变量 privateVar: " << privateVar << endl;}private:int privateVar; // 私有成员变量,类外无法直接访问void privateFunction() { // 私有成员函数,类外无法直接访问cout << "这是一个私有成员函数。" << endl;}protected:int protectedVar; // 保护成员变量,类外无法直接访问,派生类可访问void protectedFunction() { // 保护成员函数,类外无法直接访问,派生类可访问cout << "这是一个保护成员函数。" << endl;}
};class Derived : public Example {
public:Derived(int pub, int pri, int prot) : Example(pub, pri, prot) {}void accessProtected() {cout << "派生类访问基类的保护成员变量 protectedVar: " << protectedVar << endl;}
};int main() {Example example(1, 2, 3);// 访问公有成员example.publicVar = 10;cout << "公有成员变量 publicVar: " << example.publicVar << endl;example.publicFunction();// 尝试访问私有和保护成员(会报错)// example.privateVar = 20; // 错误:无法访问私有成员// example.protectedVar = 30; // 错误:无法访问保护成员// 派生类访问保护成员Derived derived(1, 2, 3);derived.accessProtected();return 0;
}
十八、构造函数、析构函数
构造函数、析构函数是类中两种特殊的成员函数
构造函数主要用于对象分配空间以及对对象的数据成员进行初始化。
析构函数主要用于释放对象及各语句所占的存储空间。
- 构造函数的特点:
- 没有返回值类型:int char func()这些前缀没有
- 函数名与类名相同:class 类名{ 类名(){}}
- 参数可以有可列个,可重载
- 可带一个成员初始化列表,写在形式参数列表的右圆括号之后、函数体的左花括号之前,用一个冒号开始。
- 构造函数可写可不写,不写 类会自动生成
class MyClass {
private:int a;const int b;
public:MyClass(int x, int y) : a(x), b(y) { // 使用成员初始化列表初始化 a 和 b// 构造函数体}
};
- 调用构造函数:
- 对象定义
- new类名或者new类名[长度]调用缺省构造函数
- new类名调用构造函数
- 类名调用构造函数
- 析构函数的特点:
- 函数名在类名前加~符号
- 不允许有参数、不允许重载
- 无返回类型
- 调用析构函数:
- 复合语句执行结束、函数执行结束、程序执行结束
- 执行delete对象或者delete[]对象数组时释放new所动态分配的存储空间
十九、构造、析构函数调用顺序
#include <iostream>
using namespace std;class Demo {
public:Demo() { // 构造函数cout << "构造函数被调用" << endl;}~Demo() { // 析构函数cout << "析构函数被调用" << endl;}
};void createObject() {cout << "进入 createObject 函数" << endl;Demo obj; // 函数内部创建的对象cout << "即将退出 createObject 函数" << endl;
}int main() {cout << "进入 main 函数" << endl;Demo obj1; // 在 main 中创建的对象cout << "创建 obj1 完成" << endl;createObject(); // 调用函数,函数内创建临时对象cout << "退出 createObject 函数,回到 main" << endl;cout << "即将结束 main 函数" << endl;return 0;
}
进入 main 函数
构造函数被调用 // obj1 的构造函数
创建 obj1 完成
进入 createObject 函数
构造函数被调用 // createObject 函数中的 obj 的构造函数
即将退出 createObject 函数
析构函数被调用 // createObject 函数中 obj 的析构函数
//这里是因为这个obj局部变量,看生存期函数结束 =>看 十五的表格!
//obj生存期到期要被释放所以这里析构函数被调用
退出 createObject 函数,回到 main
即将结束 main 函数
析构函数被调用 // main 中 obj1 的析构函数
二十、拷贝构造函数
类的特殊成员函数,用已定义的对象来初始化另一个被创建的对象
- 特点:
- 同为构造函数,与本类类名且不允许有返回类型
- 第一个参数必须为本类对象的引用,若有其他参数必须均可缺省