C++的编译开发环境
在虚拟机Ubuntu上使用g++
g++是Linux中C++的编译器,需要安装,g++的使用方法和gcc一样
测试系统是否有g++
g++ -v
安装:
sudo apt-get update
sudo apt-get install g++
使用vscode
编译需要安装minGW
使用Qt Creator
Qt Creator是Qt的集成开发环境,可以编译和运行C++程序,安装包可以直接从官网下载。
安装注意事项:
(1)如果安装时需要填Qt的ID和密码,没有直接在下方直接用邮箱注册一个使用(填入邮箱和密码)
(2)安装时除了默认内容外,只需要选择MinGW编译器即可
C++简介
历史
上世纪80年代初,本.贾尼
83年,正式命名为C++,87年,GNU C++92年,微软 C++,98年,ANSI C++
ISO C++98 ,ISO C++03 ,ISO C++11 ,ISO C++14,ISO C++17,ISO C++20
C++和C的关系
C是C++的基础,C++是C的扩展
扩展的内容:
- 1.面向对象(以类的方式组织代码) 2.运算符的重载(一种特殊的函数形式) 3.异常(一种全新的错误处理方法) 4.泛型编程(类型通用的实现)
C++的类型检查比C严格,C++完全兼容C
#include <iostream>
#include <string>
#include <list>
//#include <stdio.h> //c里面的写法
#include <cstdio> //写成这样比较好
int main()
{
printf("第一个C++程序!\n");
return 0;
}
C++的基础语法
源代码的保存
C++的源代码保存在后缀为.cpp的文件中,头文件的后缀是.h(.hpp)
.cc .C .cxx .c++
C++的头文件
C++包含自定义的头文件时不再以.h作为结尾
#include <iostream>//支持输入输出的头文件
#include <string>
#include <list>
//...
C语言的标准头文件任然可用
#include <stdio.h>
#include <stdlib.h>
//但是C++推荐使用以下语法
#include <cstdio>
#include <cstdlib>
//非标准头文件不支持该语法
#include <pthread.h>
//#include <cpthread>//错误
自定义头文件的语法和C语言没有区别
命名(名字)空间
命名空间的作用就是进行代码划分,防止命名冲突
定义一个命名空间
namespace 空间名{
变量的声明和定义;
函数的声明和定义;
.....
};
命名空间的访问
1.直接在访问内容前加上命名空间名
命名空间名::内容;
2.使用using声明在接下来的代码中使用某个命名空间中的数据
using 命名空间名::内容;
//防止冲突
3.使用using对命名空间的内容进行整体使用
using namespace 命名空间名;
//防止冲突
匿名命名空间(不要这样使用)
如果一个数据不属于任何命名空间,C++编译器就会将其加入到匿名命名空间,可以使用以下语法来访问匿名命名空间中的内容
::内容;
也可以直接定义匿名命名空间
namespace{
内容;
}
命名空间的嵌套
命名空间中还有命名空间
namespace ns1{
xxx;
namespace ns2{
yyy;
namespace ns3{
zzz;
}
}
};
如何访问:
ns1::xxx;
ns1::ns2::yyy;
ns1::ns2::ns3::zzz;
练习:
设计三个命名空间,每个命名空间中包含一个add函数,分别计算两个整数,两个浮点数和两个字符串的加法,返回加法的结果,分别调用它们。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
namespace ns1{
int add(int a,int b)
{
return a+b;
}
}
namespace ns2{
double add(double a,double b)
{
return a+b;
}
}
/*
这段没怎么看懂
*/
namespace ns3{
char *add(const char *s1,const char *s2)
{
char *s = (char *)malloc(strlen(s1)+strlen(s2)+1);
//这里为什么要加一 :固定要加一,拼接字符串
if(s){
strcpy(s,s1);
strcat(s,s2);
}
return s;
}
}
int main()
{
printf("10+2 = %d\n", ns1::add(10,2));
printf("3.14+2.68 = %lg\n", ns2::add(3.14,2.68));
char *str = ns3::add("hello ","GZFX2108");
printf("%s\n", str);
free(str);
return 0;
}
字符串的加法用拼接
使用Qt创建C++的工程
1.设置字符编码和系统一致
工具 ===> 选项 ===> 文本编辑器 ===> 行为 ===> 编码改为system
2.建立工程
文件 ===> 新建文件或项目 ===> Non-Qt Project ===> Plain C++ Application
设置工程名和保存路径 ===> 完成
C++的输入和输出
C++d的标注输入输出定义在std的命名空间中。
C++中所哟预定义的类和函数(包括输入输入出)都是保存在std的命名空间。
using namespace std;
使用输入输出还要包括iostream的头文件
标准输出 ---------- cout<<
cout<<可以输出任何非自定义的数据,加endl换行
可以使用cout<<xxx<<yyy<<zzz.....进行连续输出
标准输入 ---------- cin>>
cin>>代表空间的内容(变量/地址);
可以使用cin>>xxx>>yyy>>zzz....进行连续输入
C++的内存分配
C语言堆内存的管理
malloc/free
calloc ----------- 分配的内存会自动初始化为0
realloc ---------- 调整分配的堆内存的大小
C++堆内存的管理
new/delete -------- 分配和释放单个内存
new[]/delete[] ---- 分配和释放多个连续内存
语法:
申请一个类型大小的空间
类型名 *指针变量名 = new 类型;
类型名 *指针变量名 = new 类型(值);//分配同时初始化
释放一个类型大小的空间
delete 指针变量名;
申请的多个同类型大小的连续空间
类型名 *指针变量名 = new 类型[n];//n表示该类型大小的个数
释放多个同类型大小的连续空间
delete[] 指针变量名;
注意:new/delete和malloc/free的区别在于申请和释放对象内存时,在C++中不使用malloc/free,而使用new/delete。
引用(reference)
引用就是别名的意思
机器猫 小叮当 哆啦A梦
龙血武姬 龙女 希瓦娜
引用的语法
类型名& 引用名 = .....;//引用必须初始化
//以上的代码就是相当于给等号右边的内容起一个别名
引用既可以指向变量,也可以指向常量
int num = 1;
int& r_num = num;//num的应用
const int& cr = 10;//常量的引用
引用一旦初始化,引用的对象不能改变,终身为其服务,常量的应用题必须用const修饰。
引用作为函数的参数和返回值
作为函数参数
普通变量作为函数的参数只能实现值的单向传递
引用作为函数参数可以实现值的双向传递
作为函数的返回值
一般函数的返回值只能作为右值
int x = xxx(...);
如果希望函数的返回值作为左值就可以使用后引用类型
不能返回局部变量和形参的引用
可以返回静态变量 全局 堆 引用参数的引用
指针的引用和数组的引用
指针的引用
引用的地址就是原数据的地址
指针的引用就是指针的别名,通常就是用来代替二级指针
语法:
int *p = NULL;
int *&rp = p;//指针的引用
数组的引用
int arr[5];
int (&r_arr)[5] = arr;//数组的引用 数组长度应该一样
//数组的引用作为函数参数可以保留数组的特性
//同时丧失了数组传参的灵活性,基本不使用
void set_arr(int (&r_arr)[5])
{
sizeof(r_arr) ===> 20
}
void set_arr(int a[],int n)
{
sizeof(a) ===> 8
}
函数重载
C++编译器和C编译器对函数的处理有区别
1.C++中参数列表为()表示没有参数,等同于(void)
2.C++不支持隐式声明,必须前置声明
3.C++的函数不再默认返回int,必须指定返回值类型
4.C++的函数调用匹配不但匹配函数名,还匹配参数列表