C++ 从入门到放弃,资料整合(1)—— C++ 入门


一、第一个C++ 程序

一般在学习C++ 入门,都从C 开始,有了C 的基础,进军C++ 就会更加简单

下面简单说一下面向过程与面向对象的区别:
面向过程:过程既是步骤,按部就班将大型项目分解成若个小项目,特点:自定向下,强调的是算法
优点:性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源:比如单片机,嵌入式开发等一般采用面向过程开发,性能是最重要的因素。
缺点:没有面向对象易维护、易复用、易拓展

面向对象:有自己独特的个性,特点:方便地重用和修改现有的代码
优点:易维护、易复用、易拓展,由于面向对象封装、继承、多态性的特性,可以设计出低耦合的系统,使系统更加灵活、更加易于维护
缺点:性能比面向过程低

编译器:源代码 -》 编译器 -》 目标代码 -》 链接程序(启动代码、库代码) -》 可执行代码

在vs编译器的注释,打开注释的快捷键,建议在熟悉操作之后装一个番茄助手
ctrl + K, ctrl + C 注释
ctrl + K, ctrl + U 打开注释

/*流程:
 1. 创建项目
			使用软件 VS(visual studio) -> File(文件)->New(新建)->project(项目)->visual C++ -> 选择 空项目
			注意:起项目名,路径==不要出现中文名==
			
 2. 创建文件
			在源/头文件 右键 -》 添加 -》 新建项 -》 起文件名(起名尽量用英文)
		
 3. 编写代码
			main 是一个程序的入口,每个程序必须有这么一个函数,有且仅有一个
			大括号{} 就是函数体

 4. 编译运行程序
 	生成解决方案 F7
	启动调试 F5
	*/
	
#include <iostream>  //头文件
using namespave std;
int main(int argc, char* argv[])//主函数,唯一的入口函数
{
	cout << "hello world" << endl;
	system("pause");//调用系统命令,会阻塞在这里,直到有任意按键按下,与 getchar() 效果一致
	return 0;
}

注释
1、单行注释 //描述信息
2、多行注释 /* 描述信息*/
3、if 0 … endif //这样也是可以的
提示:在编译器运行时,会忽略注释的内容,不能注释嵌套

变量
作用:给一段指定的内存空间起名,方便操作这段内存
语法:数据类型 变量名 = 初始值;
实例:int a = 10;
命名规范:
1)只能使用字母、下划线、数字;
2)第一个字符不能为数字;
3)区分大小写;
4)不能用C++ 关键字作为名称。

常量
作用:用于记录程序中不可更改的数据
两种方式
1、#define 宏常量 : #define 常量名 常量值,eg #define DAY 7;
2、const 修饰的变量 const 数据类型 常量名 = 常量值,const int day = 7;
const 限定符 与 #define
1)能够明确指定类型
2)可以使用C++ 的作用域规则将定义在特定的函数或文件中
3)可以将const 用于更复杂的类型

关键字
作用:关键是C++ 中预先保留的单词(标识符)
asm if do return typedef
auto double inline short typeid
……
在定义变量或者常量的时候,不要用关键字,因为系统用了,否则会产生歧义

标识符命名规则
作用:C++规定给标识符(变量、常量)命名时,有一套自己的原则
标识符不能是关键字
只能由字母,下划线,数字组成
第一个字符必须由字母或者下划线
标识符中区分大小写
建议:给标识符命名时,争取做到见名知其意的效果,方便自己和他人阅读

二、数据类型

	C++ 规定在创建一个变量或者常量时,必须要指定出相应的数据类型,否则无法给出变量分配内存
	**整型**
	作用:整型变量表示的是整型类型的数据
	数据类型			占用空间		取值范围
	short				2字节			-2^15^ ~  2^15^-1
	int					4字节			-2^31^ ~  2^31^-1
	long					4字节			-2^31^ ~  2^31^-1
	long long			8字节			-2^63^ ~  2^63^-1

sizeof关键字
作用:利用sizeof 关键字 可以统计数据类型所占内存大小
语法:sizeof(数据类型 / 变量)
实例: sizeof(int);

实型(浮点型)
作用:用于表示小数
浮点型变量分为两种:
1、单精度float float f1 = 3.14f; 4个字节
2、双精度double 8个字节
默认情况下,输出一个小数,会显示出一个小数点后六位的有效数字
科学计数法
float f2 = 3e2;
字符型
作用:字符型变量用于单个字符
语法:char chTemp = ‘a’;

		注意:在显示字符型变量时,用单引号将字符括起来,不要用双引号
					单引号内只能有一个字符,不可以是字符串

C 和 C++ 中字符型变量只占用一个字节
字符型变量并不是把字符本身放到内存中存储,而是将对应的ASCII编码放到存储单元

转义字符
作用:用于表示一些不能显示出来的ASCII字符
现阶段我们常用的转义字符有: \n, \ \t
\b 退格
\n 换行
\ 反斜杠
" 双引号
? ?

字符串
作用:用于表示一串字符
两种风格
1、C风格字符串: char 变量名[] = “字符串值”;// char str1[] = “hello world”;
2、C++风格字符串: string 变量名 = “字符串值”;

布尔类型 bool
作用:布尔数据类型代表真或假的值 占一个字符大小
true 真
false 假

数据的输入
作用:从键盘获取数据
关键字:cin
语法: cin >> 变量

	int a;
	cin >> a;
	
	//读取一行
	char address[80];
	cin.getline(address, 80);

三、运算符

作用:用于执行代码的运算
运算符类型:算术运算符、赋值运算符、比较运算符、逻辑运算符
算术运算符:+ , - , * , / , %, ++ , – 注意:前置++ ,与后置++的区别
赋值运算符:=、 +=、 -=、 /= 、 %=
比较运算符: > 、 < 、 >= 、 <= 、== 、 !=
逻辑运算符:! 、 && 、 ||

四、程序流程结构

C/C++ 支持最基本流程的三种程序运行结构: 顺序结构选择结构循环结构

  1. 顺序结构:程序按顺序执行,不发生跳转; if, if - else, if - else if - else
  2. 选择结构:依据条件是否满足,有选择的执行相应的功能;
  3. 循环结构:依据条件是否满足,循环多次执行某段代码。
 练习案例:三只小猪称体重
 有三只小猪ABC,请分别输入三只小猪的体重,并且判断哪只小猪最轻?
 #include <iostream>
 using namespace std;
int main()
{
	int numA = 0;
	int numB = 0;
	int numC = 0;
	cout << "请依次输入小猪A,B,C的体重" << endl;
	cin >> numA >> numB >> numC;
	if(numA > numB)
	{
		if(numB > numC)
		{
			cout << "最轻的是小猪 C" << endl;
		}
		else
		{
			cout << "最轻的是小猪 B" << endl;
		}
	}
	else
	{
		if(numA > numC)
		{
			cout << "最轻的是小猪 C" << endl;
		}
		else
		{
			cout << "最轻的是小猪 A" << endl;
		}
	}
	system("pause");
	return 0;
}

三目运算符
作用:通过三目运算符实现简单的判断
语法:表达式1 > 表达式2 ? 表达式3
eg: int c = a > b ? a : b;//如果a 大于 b 为真,则返回a,并赋值给c,否则,则返回b,赋值给c
也可以作为左值 (a > b ? a : b) = 20;//判断a , b ,然后根据条件进行赋值其中一个

switch 语句
作用:执行多条件分支语句
语法:

switch(表达式)
{
	case 结果1: 执行语句; break;
	case 结果2: 执行语句; break;
	......
	default:执行语句;break;
}

注意1:switch 语句表达式类型只能是整型或者字符型
注意2:case里如果没有break,那么程序会一直向下执行

while 循环语句
作用:满足循环条件,循环执行语句
语法:while(循环条件){循环语句}
解释:只要循环条件的结果为真,就执行循环语句

案例:
	系统随机生成一个1100 之间的数字,玩家进行猜测,如果猜错,提示玩家数字过大或过小,如果猜对恭喜玩家胜利,并且退出游戏
#include <iostream>
#include "ctime"

using namespace std;
int main()
{
	srand((unsigned int)time(NULL));
	int num1 = rand() % 100 + 1;

	int num2;
	cout << "请输入0 ~ 100 的数" << endl;
	while (1)
	{
		cin >> num2;
		if (num1 > num2)
		{
			cout << "玩家数字过小" << endl;
			cout << "请重新输入0 ~ 100 的数" << endl;
		}
		else if(num1 < num2)
		{
			cout << "玩家数字过大" << endl;
			cout << "请重新输入0 ~ 100 的数" << endl;
		}
		else
		{
			cout << "恭喜玩家胜利" << endl;
			break;
		}
	}

    std::cout << "Hello World!\n";
	return 0;
}

do while 循环语句
作用:满足循环条件,循环执行语句
语法:do{循环语句}while(循环条件);
解释:与while 的区别 在于 do……while 会先执行一次循环语句,再判断循环条件

for 循环语句
作用:满足循环条件,循环执行语句
语法:for(起始表达式;条件表达式;末尾表达式) {循环语句;}
eg : for(int i = 0; i < 10; ++i)

嵌套循环
作用:在循环体重再嵌套一层循环,解决一些实际问题

跳转语句

  1. break 语句
    作用:用于跳出选择结构 或 循环结构
    break使用的时机:
    出现在switch条件语句中,作用是终止case 并跳出switch
    出现在循环语句中,作用是跳出当前的循环语句
    出现在嵌套中,跳出最近的内存循环结构
  2. continue 语句
    作用:在循环语句中,跳过本次循环中余下尚未执行的语句,继续执行下一次循环
  3. goto 语句
    作用:可以无条件跳转语句
    语法:goto 标记;
    解释:如果标记的名称存在,执行到goto 语句,会跳转到标记的位置

五、数组

所谓的数组,就是一个集合,里面存放了相同类型的数据元素
特点1:数组中的每个数据元素都是相同的的数据类型
特点2:数组是由连续的内存位置组成的

注意:数组下标从0开始
定义方式:

  1. 数据类型 数组名[数组长度];
  2. 数据类型 数组名[数组长度] = {值1, 值2 ……};
  3. 数据类型 数组名[] = {值1, 值2……};

实例:

int main()
{
	int score[10];
	
	score[0] = 100;
	score[1] = 99;
	return 0;
}

一维数组数组名
一维数组名称的用途:

  1. 可以统计整个数组在内存中的长度
  2. 可以获取数组在内存中的首地址
#include <iostream>
using namespace std;
int main(void)
{
	int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9 10};
	cout << sizeof(arr) << endl;//整个数组占用内存空间为
	cout << sizeof(arr[0]) << endl;//每个元素占用内存空间
	return 0;
}

练习案例1:
在一个数组中记录了五只小猪的体重,如:int arr[5] = {300, 350, 200, 400, 250};
找出并打印最重的小猪体重

练习案例2:
请声明一个5个元素的数组,并且将元素逆置
(如原数组元素为:1,3,2,5,4 逆置输出结果为:4,5,2,3,1)

冒泡排序
作用:最常用的排序算法,对数组内的元素进行排序
1、比较相邻的元素,如果第一个比第二个大,就进行交换
2、对每一个相邻元素做同样的工作,执行完毕后,找到第一个最大值
3、重复以上的步骤,每次比较次数-1,直到不需要比较

二维数组
在一维数组上多加一个维度
四种定义方式:
1、数据类型 数组名[ 行数 ][ 列数 ];
2、数据类型 数组名[ 行数 ][ 列数 ] = {{数据1,数据2}, {数据3, 数据4}};//建议用这个,直观
3、数据类型 数组名[ 行数 ][ 列数 ] = {数据1,数据2,数据3, 数据4};
4、数据类型 数组名[ ][ 列数 ] = {数据1,数据2,数据3, 数据4};

应用案列:
有三名同学(张三,李四,王五),在一次考试中的成绩分别如下表,请分别输出三名同学的总成绩
语文 数学 英语
张三 100 100 100
李四 90 50 100
王五 60 70 80

int main(void)
{
	int score[3][3] = {{100, 100, 100}, {90, 50, 100}, {60, 70, 80}};
	for(int i = 0; i < 3; ++i)
	{
		int sum = 0;
		for(int j = 0; j < 3; ++j)
		{
			sum += score[i][j];
			cout << sum << endl;
		}
	}
	return 0;
}

六、函数

作用:将一段经常使用的代码封装起来,减少重复代码
一个较大的程序,一般分为若干个程序块,每个模块实现特定的功能。

double (pf) (int);// 函数指针
doubel
pf (int);// 指针函数

函数的定义:
1、返回值类型
2、函数名
3、参数表列
4、函数体语句
5、return 表达式

语法:
返回值类型 函数名(参数列表)
{
函数体语句;
return 表达式;
}

int Add(int num1, int num2);//声明

int main(void)
{
	int a = 1;
	int b = 2;
	int sum = Add(a, b);//调用,实参
	cout << sum << endl;
	return 0;
}

int Add(int num1, int num2)//定义,形参
{
	return num1 + num1;
}

值传递
所谓的值传递,就是函数调用时实参将数值传入给形参
值传递时,如果形参发生,并不会影响实参

void swap(int a, int b)
{
	int temp;
	temp = a;
	a = b;
	b = temp;
	return;
}

声明可以有多次,定义只能有一次

函数分文件编写
作用:让代码结构更加清晰
1、创建后缀名为.h 的头文件
2、创建后缀名为.cpp 的源文件
3、在头文件中写函数的声明
4、在源文件中写函数的定义

七、指针

指针的作用:可以通过指针间接访问内存
内存编号是从0开始记录的,一般用十六进制数字表示
可以利用指针变量保存地址

指针变量的定义和使用
指针变量定义的语法: 数据类型 * 变量名;

//指针
int* p_updatas;//野指针
int* ptr = NULL;// 空指针

//使用 new 来 分配内存
int* pn = new int;//申请int 型内存


int main()
{
	int a = 10;
	int *p = &a;
	cout << &a << endl;
	cout << p << endl;
	return 0;
}

指针所占内存空间 4个字节

空指针和野指针
空指针:指针变量指向内存中编号为0的空间
用途:初始化指针变量
注意:空指针指向的内存是不可以访问的

实例:空指针
int main()
{
	//指针变量p指向内存地址编号为0的空间
	int * p = NULL;

	//访问空指针报错
	//内存编号为0 - 255为系统占用内存,不允许用户空间
	cout << *p << endl;
}
实例:野指针
int main()
{
	//指针变量p指向内存地址编号为0x1100的空间
	int * p = (int *)0x1100;

	//访问野指针报错
	cout << *p << endl;
	system("pause");
	return 0;
}

const 修饰指针
const 修饰指针有三种情况:
1、const 修饰指针 —常量指针
2、const 修饰常量 ----指针常量
3、const 即修饰指针,又修饰常量

	const int *p1 = &a;//指针指向的值不可更改
	int * cosnt p2 = &a;//指针的指向不可更改,值可以改
	const int* const p3 = &a;//指针的指向不可更改,值也不可以更改

指针和数组
作用:利用指针访问数组中元素

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;
		p++
	}
	system("pause");
	return 0;
}

指针和函数
作用:利用指针作函数参数,可以修改实参的值

//地址传递
void swap(int* p1, int* p2)
{
	int temp = *p1;
	*p1 = *p2;
	*p2 = temp;
}

指针、数组、函数
案例描述:封装一个函数,利用冒泡排序,实现对整形数组的升序排序
例如数组: int arr[10] = {4, 3, 6, 9, 1, 2, 10, 8, 7, 5};

实例:
//冒泡排序函数
void bubbleSort(int *arr, int len)
{
	for(int i = 0; i < len - 1; ++i)
	{
		for(int j = 0; j < len - 1 - i; ++j)
		{
			if(arr[j] > arr[j +1])
			{
				int temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp;
			}
		}
	}
	return;
}

八、结构体、共用体、枚举

结构体属于用户自定义的数据类型,允许用户存储不同的数据类型

语法:struct 结构体名 { 结构体成员列表 };
通过结构体创建变量的方式有三种:
struct 结构体名 变量名
struct 结构体名 变量名 = {成员1值, 成员2值 ……};
定义结构体时顺便创建变量

struct student
{
	string name;//名称
	int age;//年龄
	int score;//分数
};

union one4all
{
int int_val;
long long_val;
double double_val;
};//注意大端模式和小端模式之分


//枚举
enum spectrum{red, orange, yellow, green, violet};
spectrum myflag;
myflag = spectrum(1);

结构体指针
作用:通过指针访问结构体中的成员
利用操作符 -> 可以通过结构体指针访问结构体属性

struct student stu = {"张三", 10, 100};
struct student * p = stu;
cout << "姓名:" << p->name << "年龄:" << p->age << "分数:" << p->score << endl;

结构体嵌套

struct Teacher
{
	int id;
	string name;
	int age;
	struct Student stu;
};

结构体做函数参数
作用:将结构体作为参数向函数中传递
传递方式有两种:
值传递
地址传递
总结:如果你不想修改主函数中的数据,用值传递,反之用地址传递

结构体中 const 使用场景
作用:用const 来防止误操作
示例:
void PrintStudent(const Student* std);
在函数内不允许对变量 std 进行操作

案例:
	学校正在做毕设项目,每名老师带领五个学生,总共有3名老师,需求如下:
	设计学生和老师的结构体,其中在老师的结构体中,有老师姓名和一个存放五名学生的数组作为成员
	学生的成员有姓名、考试分数,创建数组存放三名老师,通过函数给每个老师及所带的学生赋值
	最终打印出老师数据以及所带的学生数据。
	struct Student
	{
		string name;
		int score;
	};
	struct Teacher
	{
		string name;
		struct Student stu[5];
	};
	
	void GetValue(struct Teacher *T, int len);
	void PrintInfo(const struct Teacher *T, int len);
	int main(void)
	{
		struct Teacher T[3];
		GetValue(T, sizeof(T)/sizeof(T[0]));
		PrintInfo(T, sizeof(T)/sizeof(T[0]));
		return 0;
	}

九、异常的基本语法

//尝试执行一段 可能出现异常的代码
class MyException
{
public:
	MyException() 
	{
		cout << "构造函数" << endl;
	}
	~MyException()
	{
		cout << "析构函数" << endl;
	}
	MyException(const MyException& e)
	{
		cout << "MyException 拷贝构造函数调用" << endl;
	}
};

int myDivide(int a, int b)
{
	if (b == 0)
	{
		//a = a / b;
	}

	throw MyException();
	return 0;
}


int main()
{
	int a = 0;
	int b = 0;
	try
	{
		int ret = myDivide(a, b);
		cout << "ret 结果为:" << ret << endl;
	}
	catch (int)//捕获异常
	{
		cout << "int 类型" << endl;
	}
	catch (double)//捕获异常
	{
		throw;//继续向上抛
		cout << "double 类型" << endl;
	}
	catch (MyException e)
	{
		//e.printError();
		int ddd = 0;
	}
	catch (...)
	{
		cout << "其他类型的捕捉" << endl;
	}
==========================================
//使用系统标准异常
#include <stdexcept>

class MyException
{
public:
	MyException() 
	{
		cout << "构造函数" << endl;
		throw length_error("0 ~ 150");
	}
	~MyException()
	{
		cout << "析构函数" << endl;
	}
	MyException(const MyException& e)
	{
		cout << "MyException 拷贝构造函数调用" << endl;
	}
};

try
{
	MyException p1;
}
catch(exception& e)
{
	cout << e.what() << endl;
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

C葭葭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值