C++基础知识回顾与复习

欢迎大家来一块学习与进步,此文章旨在进行C++的基础知识回顾,后续会针对C++特性进行复习总结,此文章请核心关注代码块中的注释总结

相关资料有需要的可以评论或者私信!!!

1.基础模版与注释方式

1.1基础模版

cpp 复制代码
#include <iostream>
using namespace std;

int main() {

	system("pause");

	return 0;
}

1.2注释方式

cpp 复制代码
#include<iostream>
using namespace std; 
/*
	添加多行注释
	main 函数是一个函数的入口,
	每个程序必须有一个这样的函数,
	有且只有一个!!!
*/
int main() {
	// 添加单行注释
	cout << "hello world" << endl;

	return 0;
}

2.变量与常量

2.1变量

cpp 复制代码
#include <iostream>
using namespace std;

int main() {

	// 变量的定义
	// 语法:数据类型 变量名 = 初始值;

	int a = 5;

	cout << "a = " << a << endl;

	return 0;
}

2.2常量

cpp 复制代码
#include <iostream>
using namespace std;

/*
* 常量的定义方式:
* #define 宏常量
* const 修饰的变量
*/

#define Day 7 //常量不可修改

int main() {

	const int a = 1;

	cout << "Day = " << Day << ",a = " << a << endl;
	return 0;
}

3.关键字与标识符

3.1关键字

**作用:**关键字是C++中预先保留的单词(标识符)

  • 在定义变量或者常量时候,不要用关键字

C++关键字如下:

asm do if return typedef
auto double inline short typeid
bool dynamic_cast int signed typename
break else long sizeof union
case enum mutable static unsigned
catch explicit namespace static_cast using
char export new struct virtual
class extern operator switch void
const false private template volatile
const_cast float protected this wchar_t
continue for public throw while
default friend register true
delete goto reinterpret_cast try

3.2标识符

cpp 复制代码
#include <iostream>
using namespace std;

int main() {

	/*
	* 标识符不能是关键字
	* 只能由字母、数字、下划线组成
	* 第一个字符必须为字母或者下划线
	* 区分大小写
	*/

	// 见名知意!!!

	return 0;
}

4.数据类型与运算符

4.1数据类型

cpp 复制代码
#include <iostream>
#include <string>
using namespace std;

/*
* sizeof 关键字
* 用法:sizeof( 数据类型/变量 )
*/

/*
* 整型:short, int, 
*		long(Linux中32位系统为4位,64位系统为8位), long long
* 浮点型:float, double
*		科学计数法(例如:3e2 -> 3 * 10^2,3e-2 -> 3 * 0.1^2)
* 		默认情况下 输出小数会显示6位有效数字
* 字符型:char
*		语法: char ch = 'a';
*		字符型变量并不是把字符本身放到内存中,而是将其对应的ASCII编码放入到内存中
*		cout << (int)ch << endl;
*		'a' - 'A' = 32, A = 65, a = 97, 0 = 48 
* 转义字符:反斜杠\  用于表示一些不能显示出来的ASCII字符
*		\n 换行,\\ 反斜杠,\t 制表符(补满8个字符位)
* 字符串型:C语言风格:char 变量名[] = "字符串值";
*			Cpp风格:  string 类型名 = "字符串值";  #include<string>
* 布尔类型: true(1)	false(0)	单字节	
*			 用法:bool 变量名 = true/false;
* 数据的输入:cin >> 变量
*/

int main() {

	float f1 = 3.14f; // (默认情况下编译器会将其认为双精度)
	string str = "abcde";
	cout << str << endl;

	/*string a = "hello";
	cout << "请输入字符串型变量a的值:" << endl;
	cin >> a;
	cout << "字符串变量:" << a << endl;*/

	bool flag = false;
	cout << "请给布尔类型变量赋值:" << endl;
	cin >> boolalpha >> flag;
	cout << "布尔类型变量:" << flag << endl;

	return 0;
}

4.2运算符

cpp 复制代码
#include <iostream>
using namespace std;

/*
* 算术运算:
* 加减乘除:+ - * /
*	除法:两个数相除,除数不为0;两小数可相除
* 取余:%
*	本质就是求余数,操作对象必须为整型
* 自增自减 区分前置和后置
*	前置:先变量 +/- 1后运算表达式;后置:先运算表达式后 +/- 1
* ------------------------------------------------------------
* 赋值运算:= , += , -= , *= , /= , %=  
* 比较运算符:== , != , < , > , <= , >=
* 逻辑运算符:! , && , ||
* 位运算:&(位与),|(位或),^(异或),~(取反),
         <<(左移,低位补0),>>(右移,高位补符号位或无符号补0)    ->乘以/除以2的n次
*/

int main() {

    int arr[] = { 10, 20, 30, 40 };
    int* p = arr;

    printf("初始: p指向arr[0]=%d\n", *p);

    // 情况1: *p++
    printf("*p++ = %d\n", *p++);  // 输出10,p指向arr[1]
    printf("现在p指向: %d\n", *p);  // 输出20

    // 情况2: *++p
    printf("*++p = %d\n", *++p);  // 先p++指向arr[2],输出30
    printf("现在p指向: %d\n", *p);  // 输出30

    // 情况3: ++*p 等价于 (*p)++
    printf("++*p = %d\n", ++*p);  // *p自增1,输出31
    printf("现在*p的值: %d\n", *p);  // 输出31

	return 0;

}

5.程序流程结构与数组

5.1程序流程结构

cpp 复制代码
#include <iostream>
using namespace std;
#include <ctime>

/*
* 选择结构:
	单行if语句( if(){} ),多行if语句( if(){} else {} ),
	多行if语句( if(){} else if(){} ... else{} ),
	if语句嵌套( if( if(){} else{} ){} else{} )
	三目运算符	表达式1?表达式2:表达式3 ( 真执行前者表达式,假执行后者表达式 )
		特殊的,在C++中三目运算符返回的是变量,可以继续赋值
	switch语句( switch(条件){ case 结果1: 语句;break; ... default:语句; } )
		条件必须是整数或者字符,结果n是常量表达式
	比较:与if语句比,对于多条件判断时,switch的结构清晰,执行效率高,缺点是switch不可以判断区间
* 循环结构:
	while语句( while(循环条件){循环语句;} )
	do while语句( do{循环语句;} while(循环条件); )
	for语句( for(;;){  } )
	嵌套循环
* 跳转语句:
	break关键字:用于跳出循环结构 或者 选择结构
		switch语句,循环语句,嵌套循环结构
	continue语句:在循环语句中跳过本次循环剩余未执行部分进行下一次循环
	goto语句:可用于无条件跳转到指定标记位置(特殊的也可以用作循环)
		goto 标志;		->		标志:
*/

int main() {

	int score = 0;
	cin >> score;
	if (score >= 600) {
		if (score >= 700)
			cout << "恭喜你考上北大" << endl;
		else 
			cout << "恭喜你考上一本" << endl;
	}
	else if (score >= 500)
		cout << "恭喜你考上二本" << endl;
	else if (score >= 400)
		cout << "恭喜你考上三本" << endl;
	else
		cout << "很遗憾你未考上本科" << endl;
	//---------------------------------------
	int a = 20, b = 30;
	(a > b ? a : b) = 100;
	cout << "a = " << a << ",b = " << b << endl;
	//---------------------------------------
	srand((unsigned int)time(NULL)); // 随机数种子
	int num = rand() % 100 + 1;
	//---------------------------------------


	system("pause"); 

	return 0;

}

5.2数组

cpp 复制代码
#include <iostream>
using namespace std;

/*
* 一维数组
	定义方式:数据类型 数组名[ 数组长度 ];	数据类型 数组名[ 数组长度 ] = {值1,值2,...};
			  数据类型 数组名[  ] = {值1,值2,...};
	特点:放在一块连续内存空间中;每个元素都是相同的类型;定长数组未给满数据时补0/空
	数组名用途:统计整个数组在内存中的长度;获取数组在内存中的首地址;数组名是一个常量不可以被修改或者赋值
* 二维数组
	定义方式:数据类型 数组名[ 行数 ][ 列数 ];	
			  数据类型 数组名[ 行数 ][ 列数 ] = { {数据1,数据2 } ,{数据3,数据4 } };
			  数据类型 数组名[ 行数 ][ 列数 ] = { 数据1,数据2,数据3,数据4};
			  数据类型 数组名[  ][ 列数 ] = { 数据1,数据2,数据3,数据4};
	数组名用途:查看二维数组所占内存空间;查看二维数组首地址(第一行地址(注意虽然和第一个元素的地址数值一样但是类型不同))
				二维数组名会退化为指向第一行的指针,类型为 指向一维数组的指针
					int arr[3][4];// arr 的类型是 int (*)[4],指向包含 4 个 int 的一维数组
					int (*p)[4] = arr;  // 正确:p 指向第一行
*/
void sort(int arr[], int len) {
	for (int i = 0; i < len-1; i++) {
		for (int j = 0; j < len-i-1; j++) {
			if (arr[j] > arr[j+1]) {
				int temp = arr[j+1];
				arr[j+1] = arr[j];
				arr[j] = temp;
			}
		}
	}
	for (int i = 0; i < len-1; i++) {
		if (i == len-2) {
			cout << arr[i];
		}
		else {
			cout << arr[i] << ",";
		}
	}
	cout << endl;
}

int main() {

	//char arr[5] = {'a','b'};
	//float arr[5] = { 3.14,2.28 };
	int arr[10] = { 3,7,5,9,0,-2,12,89,56,90 };
	int len;
	len = sizeof(arr) / sizeof(arr[0]);
	/*for (int i = 0; i < len; i++) {
		cout << arr[i] << endl;
	}*/

	sort(arr, len);
	//------------------------------------------
	int arr1[2][3] =
	{
		{1,2,3},
		{4,5,6}
	};
	cout << "二维数组大小: " << sizeof(arr1) << endl;
	cout << "二维数组一行大小: " << sizeof(arr1[0]) << endl;
	cout << "二维数组元素大小: " << sizeof(arr1[0][0]) << endl;

	cout << "二维数组行数: " << sizeof(arr1) / sizeof(arr1[0]) << endl;
	cout << "二维数组列数: " << sizeof(arr1[0]) / sizeof(arr1[0][0]) << endl;
	//地址
	cout << "二维数组首地址:" << arr1 << endl;
	cout << "二维数组第一行地址:" << arr1[0] << endl;
	cout << "二维数组第二行地址:" << arr1[1] << endl;

	cout << "二维数组第一个元素地址:" << &arr1[0][0] << endl;
	cout << "二维数组第二个元素地址:" << &arr1[0][1] << endl;

	system("pause");
	return 0;
}

6.函数规范及分文件编程示例

main函数:

cpp 复制代码
#include "swap.h"

/*
* 函数:
	语法:返回值类型 函数名( 形参列表 ){	函数体语句;		return表达式;	}
	调用:函数名( 实参 );	值传递和址传递
	样式:无参无返,有参无返,无参有返,有参有返
	函数声明:返回值类型 函数名( 形参列表 );
		提前告知编译器函数的存在!
		声明可以多次编写,但是定义只能有一份!
* 分文件编写:
	实现步骤:创建头文件(.h),创建源文件(.cpp),在头文件中声明,在源文件中定义
*/

int main() {
	int a = 10, b = 20;
	swap(a, b);

	return 0;
}

分文件函数:

cpp 复制代码
//头文件
#pragma once
#include<iostream>
using namespace std;

//实现两个数字交换的函数声明
void swap(int a, int b);
cpp 复制代码
//源文件
#include"swap.h"

void swap(int a, int b) {

	int temp = a;
	a = b;
	b = temp;

	cout << "a = " << a << endl;
	cout << "b = " << b << endl;
}

7.指针

cpp 复制代码
#include <iostream>
using namespace std;

/*
* 指针:
	用途:可以通过指针间接访问内存地址
		内存编号是从0开始记录,一般用十六进制数表示;可以利用指针变量保存地址
	定义:数据类型* 指针变量名;	示例:int* p;	p = &a;
	解引用:*指针变量名
		获取指针指向内存地址的数据,可用于读取或者修改!
	内存空间:大小恒定	->	64位系统:8字节;32位系统:4字节
	空指针:指针变量指向内存中编号为0的空间		int *p = NULL;
		用于初始化指针变量;空指针指向的内存空间不可访问
	野指针:指向非法的内存空间
		示例:随便指向一个数字:int *p = (int *)0x1100;	(×)
* const关键字:
	const修饰指针的三种形式:	const往右看,看离得谁近谁就不可以修改(也可从右往左读)/const读作常量,*读作指针,看位置读
		常量指针(const修饰指针):const int* p = &a;/int const * p;	指针的指向可以修改,指针指向的值不可修改。
			p是指针,指向const int类型的数据
		指针常量(const修饰常量):int * const p = &a;	指针的指向不可以修改,指针指向的值可以修改。(指针是一个常量)
			p是const类型的指针,指向int类型的数据
		指向常量的常量指针:const int * const p = &a;/int const* const p;
			p是const类型的指针,指向const int类型的数据
* 指针和数组:
	利用指针访问数组中的元素	int arr[10];	int *p = arr;	*p;/p++;(指针向后偏移4字节)*p;
	* 与 前++优先级一致,从右往左进行运算( *++p/++*p );
		前++ 先自身+1后干别人让干的事:*++p(先给p+1后解引用),++*p(先对*p进行+1后去干别人让干的事)
	后++时,从左往右运算,可以理解为先进行 * 解引用后++( *p++ )
		实际 "后++" 优先级高于 "*" ,编译器底层会开辟无名空间,先保存当前p指向的地址后进行p+1操作,然后解引用保存的原先地址
* 指针与函数:
	利用指针作为函数形参可以改变实参的值,即地址传递	swap(&a, &b); //地址传递会改变实参
	void swap(int *p);	/	void swap(int arr[]);	/	void swap(int arr[n]);//n可以为任意合法值,但是编译器会忽略这里的数组大小
    优势在于形参为指针可以减少内存空间占用,而且不会复制新的副本出来
*/

int main() {

	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };

	int* p = arr;  //指向数组的指针

	cout << "第一个元素: " << arr[0] << endl;
	cout << "指针访问第一个元素: " << *p << endl;

	for (int i = 0; i < 10; i++)
	{
		//利用指针遍历数组
		cout << *p++ << endl;
		
	}

	system("pause");

	return 0;
}

8.结构体

cpp 复制代码
#include <iostream>
using namespace std;

/*
* 结构体:
	* 定义:属于用户自定义的数据类型,允许用户存储不同的数据类型
	* 语法:struct 结构体名 { 结构体成员列表; };
	* 创建变量方式:
		struct 结构体名 变量名	
		struct 结构体名 变量名 = { 成员1值 , 成员2值...}
		定义结构体时顺便创建变量
		!!!	创建变量时在C++中 struct 关键字可以省略:Student s1;
				C语言中通常不可以省略,可以用typedef定义别名:
					typedef struct Node{}Node;	typedef struct{}Node;
	* 结构体变量访问方式:
		方式1:struct Student s1;// 创建结构体变量	s1.id = 1001;// 点运算符访问成员
		方式2:struct Student s1 = {1001, "张三", 95.5};	struct Student *ptr;  // 结构体指针
			   ptr = &s1;  // 指向s1	ptr->score = 98.0;// 箭头运算符访问与修改成员
			   !!!	ptr->name 等同于   (*ptr).name
	* 结构体数组:struct  结构体名 数组名[元素个数] = {  {} , {} , ... {} }
	* 结构体指针:利用操作符 -> 可以通过结构体指针访问结构体属性
	* 结构体嵌套结构体:在结构体中可以定义另一个结构体作为成员,用来解决实际问题
	* 结构体做函数参数:值传递和地址传递
		值传递:void printStudent( student stu ){}	//依旧可以省略struct关键字
		地址传递:void printStudent2(student *stu){}	//	!!!	通常在C++中想修改实参不采用传递指针,而是采用别名引用(后续)
	* 结构体中const关键字的使用:
		用const来防止误操作!!!	->	常量指针
			void printPoint(const struct Point* p) { 
				// p->x = 10;  // 错误!不可修改
				printf("(%d, %d)\n", p->x, p->y);
			}
*对齐补齐规则:
	* 对齐:每个成员的起始地址必须是其类型大小的整数倍;结构体总大小必须是最大成员对齐值的整数倍;
	* 补齐:不满足对齐规则就补
	* 优化规则:
		从大到小排列成员:double → long → int → short → char
		相同类型放一起:减少补齐
		数组放在最后:避免拆分
		1字节成员最后:char、bool放末尾
		考虑缓存行:对齐到64字节边界
		网络传输用1字节对齐:避免平台差异	#pragma pack(1)
		性能敏感结构体单独优化:不要依赖默认对齐
	* 修改对齐方式
		#pragma pack(push, n)  // 保存当前对齐设置,并设置新的对齐值n
		#pragma pack(pop)       // 恢复之前保存的对齐设置
		#pragma pack(n)         // 直接设置对齐值n(不推荐,不保存状态)
	* 查看成员偏移量
		函数头文件:#include <cstddef>
		函数原型:offsetof(MyClass, member)
*/

//结构体类型声明
struct student{
	//成员列表
	string name;  //姓名
	int age;      //年龄
	int score;    //分数
};

int main() {

	// 省略struct关键字
	struct student stu = { "张三",18,100, };
	student* p = &stu;


	system("pause");

	return 0;
}

作者​​:趙小贞

​​声明​​:本文基于个人学习经验总结,如有错误欢迎指正!

​​版权​​:转载请注明出处,禁止商业用途。

声明:整体内容原创,用于复习总结以及分享经验,欢迎大家指点!

相关推荐
zhuqiyua5 小时前
第一次课程家庭作业
c++
5 小时前
java关于内部类
java·开发语言
好好沉淀5 小时前
Java 项目中的 .idea 与 target 文件夹
java·开发语言·intellij-idea
只是懒得想了5 小时前
C++实现密码破解工具:从MD5暴力破解到现代哈希安全实践
c++·算法·安全·哈希算法
lsx2024065 小时前
FastAPI 交互式 API 文档
开发语言
VCR__6 小时前
python第三次作业
开发语言·python
码农水水6 小时前
得物Java面试被问:消息队列的死信队列和重试机制
java·开发语言·jvm·数据结构·机器学习·面试·职场和发展
wkd_0076 小时前
【Qt | QTableWidget】QTableWidget 类的详细解析与代码实践
开发语言·qt·qtablewidget·qt5.12.12·qt表格
东东5166 小时前
高校智能排课系统 (ssm+vue)
java·开发语言
余瑜鱼鱼鱼6 小时前
HashTable, HashMap, ConcurrentHashMap 之间的区别
java·开发语言