一、介绍
(1) C++是C的继承。
(2) C++即擅长面向对象的程序设计,又能做面向过程的程序设计。
一、工程代码和命名空间
1. C++编译器
使用g++编译c++文件(C++的编译器更严格),g++也可以编译C程序。
2. C++与C的工程代码区别:
(1) C++源文件的后缀名 .cpp .C .cxx .cc 。
(1) C++的头文件都没有.h的。
(2) << 是一个运算符重载 operator << (形参列表)。
(3) cout << 类似C程序中的 printf 函数。
(4) endl 相当于 \n。
(5) cin >> 相当于scanf 函数。
(6) string 是C++的字符串的类 类型。
3. 命名空间(名字空间)
用关键字namespace 定义自己的名字空间。防止命名污染(大型项目开发过程中,不同的开发人员定义相同的名字)。
namespace + 名字空间标识符
{
//在自定义的命名空间中定义自己的变量或函数或类。
}
(1) 使用 :: 域名访问符访问指定空间中的变量、函数或类。
(2) 当名字有冲突时,需要用命名空间名:: 来区分。
(3) 没有被任何命名空间包住的名字,默认都在匿名空间里,访问方式 ::名字。
(4) 当命名空间中的名字和局部变量冲突时,采用局部优先原则。
(5) 命名空间可以嵌套使用。
(6) 关键字using :导入名字空间标识符。用 using 导入某个变量或函数或类的标识符的用法如下:
使用方式1:using + 名字空间名 :: 某个变量标识或某个函数标识符 //具体导入
使用方式2:using + namespace + 名字空间名 //全部导入
二、结构体与字符串
1. C与C++ 的结构体区别
(1) C中的结构体是不可以有直接定义函数的 。
(2) 在C++中,定义结构体变量时,不需要再使用struct。
(3) C++中结构体无需定义函数指针进行回调,可以把函数直接定义在结构体内部。直接定义在结构体内部的函数,称为成员函数,或成员方法,或成员行为。
(4) C++中的结构体很少去定义对象,定义对象更常使用关键字 class。
(5) C++中结构体更多用于保存不同类型的数据
2. C++中的字符串
2.1 C++中支持两种风格的字符串
(1) C风格:首地址、尾0 的风格
char str1[32] = "hello";
const char* p = "hello";
(2) C++风格:C++中新增了string类型
使用string类型的要求:
必须加头文件 #include <iostream>
必须加头文件 #include <string>
必须加 using namespace std;
有些编译器加了std后,不加string也不报错。但是最好加上。
2.2 string类型的赋值和初始化
(1) 只有一个变量时:
string s1; s1 = "hello";
string s2 = "world";
string s3 ("hqyj");
string s7(5,'a'); //用“aaaaa”初始化s7 --不常用
(2) 有两个变量时:
string s4; s4 = s3;
string s5 = s2;
string s6 = s1 + s2;
3. C风格和C++风格字符串的转换
C++ --> C : 使用string类的 c_str() 函数来返回字符串的首地址 。
#include <iostream>
#include <string>
#include <cstdio>
using namespace std;
int main()
{
string s = "hello world";
//C++中不建议使用C风格的字符串
//但有些函数的参数又要求使用C风格字符串:printf sprintf fprintf
printf("s = %s\n",s.c_str());
}
C ---> C++: C风格的字符串会自动转换成C++风格。
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s = "hello";
if("hello" == s){
cout <<"yes" << endl;
}else{
cout <<"no" << endl;
}
}
4. string类的两个重要函数
(1) size()
功能:返回字符串的长度(不包括'\0')---strlen
(2) empty()
功能:返回字符串是否为空,空返回真,非空返回假。
5. string类型的输入
(1) cin可以输入string 类型,但是不能输入带有空格的字符串。
(2) 如果想输入带有空格的字符串,可以使用 getline 函数。
int main()
{
string s;
getline(cin, s);
cout << s <<endl;
}
6. string 相关API的介绍
#include <iostream>
using namespace std;
int main()
{
//string 的=号运算符重载函数
string str = "lhbaichsh";
cout << str <<endl;
//string 的at接口
cout << str.at(0) << endl;
//string 的[]接口
cout << str[3] << endl;
string str1 = "aichshi";
//string的+运算符的接口
cout << str + str1 << endl;
//string 的append 的拼接字符的接口
cout << str1.append(str) << endl;
//使用运算符重载拼接字符串的接口
string str2 = str += str1;
cout << str2 << endl;
return 0;
}
三、C++中的bool变量,&运算符
1. bool布尔变量
C++中新增bool类型,用来表示真假
bool类型只有两个值:true(1) false(0) 。
使用bool类型可以防止 魔鬼数字。
true 和false 是常量,可以用来给bool类型的变量赋值。
#include <iostream>
using namespace std;
int main()
{
bool ok; //定义一个布尔变量
ok = true; // 用true代替1
cout << ok << endl;
ok = false; //用false代替2
cout << ok << endl;
return 0;
}
bool类型的大小:
bool类型大小为1个字节,本质上bool类型有一个bit就够了,但操作系统分配内存的最小单位是字节,所以bool类型的大小才是一个字节。
2. &运算符
(1) 在函数名前&取地址:指向函数地址的函数指针
(2) 在C++指向结构体类内成员函数的函数指针必须使用&取址符
3. C与C++ const修饰符的区别
(1) 在C中,const修饰的变量叫做只读变量,可以通过指针修改。
(2) 在C++中,使用const 修饰的变量在某些情况下被称之为常量。const修饰的变量承接的是一个立即数,编译器会对此变量进行优化,把这个变量值放在寄存器中。称这种方式的变量称为符号变量。
四、C++中内联函数
(1) inline修饰的函数是内联函数。
(2) inline是C++关键字。在函数声明或定义中,函数返回类型前加上关键字inline,即可以把函数指定为内联函数。可以解决一些函数频繁调用消耗大量的栈空间(栈内存)的问题。
(3) 关键字inline 必须与函数定义放在一起才能使函数成为内联函数,仅仅将inline放在函数声明前是不起任何作用。
(4) inline是一种“用于实现”的关键字,而不是一种“用于声明”的关键字。
(5) 内联函数,保证了如同C中宏函数的高效性,同时避免了一些Bug,但代价是代码的膨胀。
(6) 内联函数一般是简短的且调用频次高的函数可声明为内联函数。
(7) 内联函数不可以延时或耗时的操作。如有,编译器将自动停止内联。
五、C++中函数参数默认值
函数参数默认值的赋值规则:
从右往左依次赋值,不可跳跃。
意义:函数调用更加灵活。
六、C++中的函数重载
1. 函数重载机制:
(1) 根据同名函数的参数不同,调用与之对应的函数。
(2) 函数重载是发生在同一作用域的。
(3) 函数重载与它函数中的参数列表中的形参的类型、个数、顺序是相关的,与它的返回值是没有关系的。
2. 函数重载的底层逻辑:
函数重载,其实是编译器在底层默默地帮我们做了工作。把同名的函数根据函数的形参列表不同,重新生成不同的函数名。其实还是不同函数的调用。
七、C++中的引用
C++引用其实是C中指针的升级版。通俗理解是变量的别名。
格式:
类型名& 引用名 = 引用的目标;
要求:
(1) 定义引用时必须要有引用的目标来初始化。
(2) 引用和引用的目标类型要保持一致。
(3) 引用的目标一旦确定了,后面就不能再修改应用的目标了。
引用最为常用的方式:
函数传参过程或函数返回过程 使用引用,可以减少空间的拷贝。
总结:引用与指针:
(1) 引用底层实现是const修饰的指针,const修饰的变量必须赋初值,所以说引用必须赋初值。
(2) 指针可以不用赋初值,不赋初值的代价就是野指针。
(3) 引用:引用了指定已经存在的空间。这块空间一定是合法空间。指针在使用前需要检查合法性。
(4) 在使用sizeof 时,引用的大小为被引用变量的大小。而指针 32位是4字节,64位是8字节。
(5) 引用只能引用一次,不可引用多次。而指针可以随意指向。
(6) 可以定义指针数组、不可以定义引用数组
(7) 可以定义数组指针,也可以定义数组引用
(8) 可以定义指针函数,也可以定义引用函数
(9) 可以定义函数指针,也可以定义函数引用
(10) 可以定义指针的指针(二级指针),不可以定义引用的引用(二级引用)
八、常引用
const修饰的引用为常引用。
如:const int& c = 100;
常引用的意义:
保护参数的安全,防止传递到函数的参数在函数内被二次修改,使函数的稳定性更强,代码更健壮!!
九、C++中动态开辟空间的方式
1. C中动态开辟空间的方式
#include <iostream>
using namespace std;
int main()
{
int* p = (int*)malloc(sizeof(int));
cout << *p << endl;
int* p1 = (int*)calloc(1,sizeof(int)); //开辟一个空间并初始化
cout << *p1 << endl;
int* p2 = (int*)realloc(p1,sizeof(int)*5);//连续开辟5个空间并初始化
cout << *(p2+1) << endl;
free(p);
free(p1);
free(p2);
return 0;
}
2. C++中新的开辟空间方式:
使用关键字new开辟空间,关键字delete释放空间。
(1) 在C++中动态开辟空间的方式,使用new在堆区按类型开辟空间,且可以在类型后加个小括号来对这个空间进行初始化。
(2) 对于连续开辟的空间,如要初始化,可以在中括号后加个大括号然后赋初值。
#include <iostream>
using namespace std;
int main()
{
int* p = new int(0);
delete p; //释放p的空间
int* p2 = new int[10]{0};
delete []p2;
return 0;
}
总结:
(1) 使用new在堆区开辟空间时,如果是自定义类类型,开辟空间的同时会调用构造函数。
(2) 使用delete释放堆区的资源时,如果是自定义类类型,会先调用析构函数然后再释放堆区空间。