一、C++基本用法
1. C++新增特性
- 类型检查更严格
- 变量引用
- 面向对象编程
- 泛型编程
- 异常处理
- 函数及运算符重载
- 命名空间
- 其他
2. VS中编译C++流程
二、C++的基本架构
1. C++默认架构
#include <iostream> //头文件
using namespace std; //域名空间
int main () { //主函数
//代码
return 0;
}
2. 头文件
标准C++程序库中不带.h,若想使用C语言的函数,需去.h在前面加c。如
stdio.h → \rightarrow → sctdio
string.h → \rightarrow → cstring
math.h → \rightarrow → cmath
3. 域名空间
用于解决命名冲突问题。
(1)在需要的时候直接使用
int main() {
std::cout << "hello" << std::endl;
}
(2)只设置所需的名称
using std::cout
using std::cin
int main() {
cout << "hello" << endl;
}
(3)using namespace
using namespace std;
int main() {
cout << "hello" << endl;
}
4. 输入输出函数
C++的输入输出通过“流”的方式实现。
-
标准输入(standrad input) :cin
-
标准输出(standardoutput) :cout
-
标准出错I(standaTCrr) :cerr
-
流输出运算符:<<
-
流输入运算符:>>
练习1:
//class_exercise/home1.cpp
#include <iostream>
#include <cstring>
using namespace std;
int charsToint(char buf[]) {
int data = 0;
for(int i = 0; i < strlen(buf); i++) {
data = data * 10 + (buf[i] - '0');
}
return data;
}
int main() {
char buf1[] = "200";
char buf2[] = "100";
int data1,data2;
data1 = charsToint(buf1);
data2 = charsToint(buf2);
cout << "data1 + data2 = " << data1 + data2 << endl;
cout << "data1 - data2 = " << data1 - data2 << endl;
cout << "data1 * data2 = " << data1 * data2 << endl;
cout << "data1 / data2 = " << data1 / data2 << endl;
return 0;
}
练习2:
//class_exercise/home2.cpp
#include <iostream>
using namespace std;
int main(){
int data = 0;
int x = 0, y = 0, z = 0;
while(data <= 99 || data >= 1000) {
cout << "请输入一个三位数:";
cin >> data;
}
z = data % 10;
y = (data % 100 - z ) / 10;
x = (data - y) / 100;
cout << "data = " << data << " ===> "
<< "x = " << x << ", y = " << y << ", z = " << z <<endl;
return 0;
}
练习3:
//class_exercise/home3.cpp
#include <iostream>
#include <string>
using namespace std;
struct Student {
string name;
int id;
double score;
};
void inputStudent(Student * student, int n) {
for (int i = 0; i < n; i++) {
cout << "student[" << i << "].name = ";
cin >> student[i].name;
cout << "student[" << i << "].id = ";
cin >> student[i].id;
cout << "student[" << i << "].score = ";
cin >> student[i].score;
cout<<endl;
}
}
void outputStudent(Student* student, int n) {
for (int i = 0; i < n; i++) {
cout << "student[" << i << "].name = " << student[i].name << endl;
cout << "student[" << i << "].id = " << student[i].id << endl;
cout << "student[" << i << "].score = " << student[i].score << endl;
cout<<endl;
}
}
int main() {
struct Student stu[3];
cout<<"请输入学生信息:"<<endl;
inputStudent(stu, 3);
cout<<"学生信息:"<<endl;
outputStudent(stu, 3);
return 0;
}
三、C++中的指针
1. 内存与地址
1.1. C++分配内存的方法
(1)定义变量
(2)malloc函数动态分配内存
1.2. C++对内存读写的方法
(1)通过内存标识符(变量名)
(2)通过内存地址
&符号获得内存的首地址
1.3. C++两种变量
(1)普通变量:保存数值
(2)指针变量:保存地址
练习:
要求通过指针变量实现data1和data2数据的交换。(至少两种方法)
#include <iostream>
using namespace std;
void swap1(int * data1, int * data2)
{
int temp;
temp = *data1;
*data1 = *data2;
*data2 = temp;
}
void swap2(int * data1, int * data2)
{
*data1 = *data1 + *data2;
*data2 = *data1 - *data2;
*data1 = *data1 - *data2;
}
int main()
{
int data1 = 10, data2 = 20;
cout << "交换前:" << "data1 = " << data1 << " data2 = " << data2 << endl;
int * p = &data1;
int * q = &data2;
swap1(p, q);
cout << "方法一:" << "data1 = " << data1 << " data2 = " << data2 << endl;
swap2(p, q);
cout << "方法二:" << "data1 = " << data1 << " data2 = " << data2 << endl;
return 0;
}
2. 指针的类型
p指向对象的数据类型为:int
p本身的数据类型为:int *
int data = 100;
int *p = &data;
-
在32位操作系统中所有的指针变量都是4个字节
-
CPU中的两种存储模式
(1)大端模式:高地址存数据的低位,低地址存储数据的高位
例如:0x12345678
低地址
0x12
0x34
0x56
0x78
高地址
(1)小端模式:低地址存数据的低位,高地址存储数据的高位
低地址
0x78
0x56
0x34
0x12
高地址
- 指针的寻址范围由数据类型决定
int * p1; //一次操作4个字节
short * p2; //一次操作2个字节
char * p3; //一次操作1个字节
- 指针变量移动时,每次移动的大小为指向数据类型的大小
练习:
1、定义10个元素的整型数组,给数组输入值,例如:1,2,3,4,5,6,7,8,9,10。要求定义两个指针变量pMax,pMin,分别保存数组中的最大值和最小值的地址。分别输出最大值和最小值的结果。
2、然后通过pMax和pMin实现最大值和最小值的交换,最后输出数组的内容。
//class_exercise/home5.cpp
#include <iostream>
using namespace std;
void swap(int * data1, int * data2)
{
int temp;
temp = *data1;
*data1 = *data2;
*data2 = temp;
}
int main()
{
int nums[10];
for(int i = 0; i < 10; i++) {
cin >> nums[i];
}
int * pMax = &nums[0];
int * pMin = &nums[0];
for(int i = 1; i < 10; i++) {
if(nums[i] > *pMax) {
pMax = &nums[i];
}
if(nums[i] < *pMin) {
pMin = &nums[i];
}
}
cout << "Max = " << *pMax << "; Min = " << *pMin << endl;
swap(pMax, pMin);
for(int i = 0; i < 10; i++) {
cout << nums[i] << " ";
}
return 0;
}
四、C++新语法
1. 引用
1.1. 引用的概念
引用:是某一个变量或对象的别名,对引用的操作与对其所绑定的变量或对象的操作完全等价。
类型 &引用名 = 目标变量名
注意:
- &不是求地址运算符,而是起标志作用
- 引 用 的 类 型 必 须 和 其 所 绑 定 的 变 量 的 类 型 相 同 \textcolor{red}{引用的类型必须和其所绑定的变量的类型相同} 引用的类型必须和其所绑定的变量的类型相同
- 声 明 引 用 的 同 时 必 须 对 其 初 始 化 , 否 则 系 统 会 报 错 \textcolor{red}{声明引用的同时必须对其初始化,否则系统会报错} 声明引用的同时必须对其初始化,否则系统会报错
- 引用相当于变量或对象的别名,因此不能再将已有的引用名作为其他变量或对象的名字或别名
1.2. 使用场景
- 在函数中相应通过形参改变实参值的时候
- 当实参比较大【数组,结构体】的时候,传递引用,系统不会生成临时变量,较少内存的消耗。
1.3. 引用的本质
引用在C++内部实现是一个常量指针。
2. 函数重载
规则:
- 函数名称必须相同。
- 参数列表必须不同(个数不同、或类型不同、参数排列顺序不同等)。
- 函数的返回类型可以相同也可以不相同。
- 仅仅返回类型不同不足以成为函数的重载。
练习:
设计一个函数求圆柱体的体积。要求用户从键盘输入一个半径,该半径可以是整数,也可以小数,分别设计对应的函数。
3. 默认值参数
-
设计默认值参数时,可以书写部分的参数,但是** 一 旦 为 某 个 参 数 指 定 了 默 认 值 , 其 后 面 的 所 有 参 数 都 必 须 有 参 数 \textcolor{red}{一旦为某个参数指定了默认值,其后面的所有参数都必须有参数} 一旦为某个参数指定了默认值,其后面的所有参数都必须有参数**
-
如果不是才函数声明时设置默认值,而是在定义中设置,那么定义一定要放在函数调用前
练习:
#include <iostream>
#include <string>
using namespace std;
void tcpInit(string ip = "127.0.0.1", int port = 8888)
{
cout << "ip = " << ip << endl;
cout << "port = " << port << endl;
}
int main()
{
tcpInit();
tcpInit("192.168.1.88", 9999);
return 0;
}
4. 堆区内存分配
4.1. C语言
//申请内存:
void * malloc (unsigned int size);
//释放内存
void free();
用法示例:
char *p = (char *)malloc(1024);
strcpy(p, "hello");
printf("p: %s\n", p);
free(p);
4.2. C++
new 向堆区申请空间
delete 释放堆区的空间
用法:
【1】普通变量:
//数据类型 *指针变量名 = new 数据类型
int *p = new int;
*p = 800;
delete p;
【2】数组
//数据类型 *指针变量名 = new 数据类型[元素个数]
int *p = new int[5];
delete p[]; //释放整个数组的大小
【3】初始化
//数据类型 *指针变量名 = new 数据类型 (初始化值)
int *p = new int (100);
4.3. 区别
malloc和new的区别:
- malloc/free是C语言中提供的库函数,new/delete是C++中的运算符;
- malloc可以在堆区分配空间,但是返回值是一个void *指针。使用要强转。
new/delete,使用的时候,系统的调度,资源少一些。直接通过指针连接收。 - new/delete,申请对象空间的时候,会调用对象的构造函数和析构函数,而malloc不会调用。