目录
一、认识C++
1、如C语言、C++、C#、Python等语言,为什么会有这么多语言存在?
2、C++解决了什么问题?
3、什么是面向对象?
4、C++的特性有什么?
二、C++的基础语法
1、编译器
2、第一个C++工程
<1>头文件
<2>名字空间--->namespace关键字
<3>using 关键字:导入或使用
3、C++中的结构体
<1>C++中对一个结构体的描述
4、C++中的字符串类型string
三、C++中的bool变量、&取址运算符、const修饰符
1、C++中的bool变量
2、C++中&取址运算符
3、C++中const修饰符
四、内联函数、函数参数默认值、函数重载机制、引用
1.内联函数
内联函数总结:
2.函数参数默认值
3.函数重载机制
补充:
4.引用
<1>引用的语法定义
<2>引用的本质
<3>底层实现
<4>引用使用实例演示
五、C++中的动态开辟空间的方式
因为语言是一种工具,当一个问题,如果可以使用更简洁高效的工具去解决时,这个工具就会被人们所使用。所以针对不同的问题就产生了不同的语言。
C++是一门面向过程与面向对象方面都比较完善的语言,同时又加入了泛型抽象思想的加持,使C++在面对开发超大型程序方面游刃有余。
面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的属性,行为。
面向对象就是高度实物抽象化、面向过程就是自顶向下的编程。
面向对象有三大特性:封装性,继承性和多态性。
C++使用g++编译器进行编译,g++向上兼容可以编译C程序。同时g++编译器对类型的检查比gcc要更加的严格。
#include
using namespace std;
int main()
{
cout<<"hello world"<
C++中标准库中的头文件一般都不带.h,同时C++为了兼容C标准库,把C标准库中的文件也都引用了过来,在所有C标准库文件前加个c
namespace + 名字空间标识符
{
//这个名字空间就是一个作用域
//在这个作用域中去定义你的变量名,函数名,类名。
}
1)using + 作用域标识符::指定的变量,函数,类名,指的是指定导入的意思。
using std::cout;//后面的代码可以使用cout(若不导入则会出现报错)
using std::endl;//后面的代码可以使用endl
//使用::逐级访问
例:
namespace A
{
int a = 100;
void showInfo()
{
cout << "22071班同学,你好!!!" << endl;
}
//作用域也是可以有嵌套的,访问嵌套作用域时,使用::域名访问符逐级访问。
namespace C
{
int a = 3000;
}
}
int main()
{
//使用::逐级访问
cout << A::C::a << endl;
使用::域名访问符逐级访问。
using A::C::a;
cout << a << endl;
return 0;
}
2)using + namespace + 作用域标识符:全部导入。(作用域中的所有的变量,函数,类标识符全部导入到当前文件中)
using namespace std;//将std的作用域中的所有变量、函数、类标识符全部导入
#include
using namespace std;
class Stu
{
public:
string name;
int age;
void write_code()
{
cout << "正在努力的写代码" << endl;
}
};
int main()
{
Stu stu = {"zhangsan",18};
cout << stu.name << endl;
cout << stu.age << endl;
stu.write_code();
return 0;
}
总结:
1)C++中结构体struct是有封装性,默认访问权限是私有的。
2)C++中定义类的关键字class也是由struct衍生而来,只不过class访问权限默认为private私有的。而struct默认的是公有的public。
3)C++struct结构体在定义对象时无需再struct关键再修饰一次了。
4)C++中struct结构中的函数,就叫成员函数。非静态成员函数可以直接调用结构中的变量,非静态成员函数行参列表中有一个隐藏的this指针,所以可以调用类中的成员属性。
<1>C++中的string相当于C语言中的字符指针或字符数组,相对于C语言更加灵活,不需要在考虑结束符\0,及字符长度越界的问题。
int main()
{
string name = "gaowanxi";//1.定义一个string 对象
string name2 = ",lisi";
cout << name + name2 << endl; //两个字符串的连接,返回值是一个新的字符串。
cout << (name += name2) << endl;
}
bool是一个类型。底层就是unsigned char 无符号字符整形。
占一个字节,只有两个值:true :真,1 false :假,0
#include
using namespace std;
int main()
{
bool ok;//定义一个bool类型的变量ok
ok = true;
cout << sizeof (ok) << endl;//判断一个bool变量的大小
cout << ok << endl;//输出此时的ok
ok = false;
cout << ok << endl;
return 0;
}
#include
using namespace std;
typedef void (*Pfun)();//
struct Stu//struct的默认权限是public
{
string name;
int age;
void showInfo()
{
cout << "姓名:" << name << ",年龄:" << age << endl;
}
};
void show()
{
cout << "22071班同学,加油!!!!" << endl;
}
int main()
{
int a = 10;
int* p = &a;
cout<<*p<(形参列表)
//获取成员函数指针:& + 作用域 ::成员函数名
void (Stu::*pfunc)() = &Stu::showInfo;
(stu.*pfunc)();
return 0;
}
//在C++中const修饰变量的几种情况
//1.const修饰的变量承接的是一个立即数(常量),那么这变量,编译器将会成其进行优化,优化成一个常量。
const int max = 1024;
//2.const修饰的变量+volatile则不会被编译器优化
const int volatile a = 100;
//3.const修饰的变量不可被修改,但是可以通过指针获取const修饰的变量的地址从而修改对应地址下的内容
int* p = (int*)&a;
*p = 500;
<1>内联函数语法形式
inline + 返回值 函数名(形参列表)
{
//内联函数体...
}
默认情况下,inline关键字是放在函数的定义处。
C++的内联函数:主要是要继承C中宏函数的高效运行效率,同时又想避免C中宏函数所出现的一些语言Bug。
C++内联函数inline关键字只是一个荐意的作用,是否进行内联,也要看具体函数代码是否精简。如果代码逻辑复杂,或者有循环,有耗时操作,有递归时,将自动停止内联。
在C++中,所有结构体,或类中的成员函数都将自动加上inline进行优化,如果成员函数是一个复杂,或有循环,或有递归时,也将停止该成员函数的内联。
内联函数是有代价的:因为其会在内嵌在主函数中的函数调用处,所以会造成最终可执行程序的代码膨胀的问题。
函数参数默认值可以理解为:当定义函数时,形参列表赋初值
#include
using namespace std;
//C++中关于函数参数默认值的赋值规则是:
//从右往左依次赋默认值(入栈),不可以跳跃。
//同时,如果使用分文件编程时:函数默认参数赋值可以只写在声明处,定义得无需再次进行赋值。
int add(int a = 1, int b = 2, int c = 3)
{
cout<<"a="<
意义:函数调用参数的灵活性。
C++的一个项目中同一作用域下允许多个同名函数同时存在,但是不能完全相同,参数类型,个数,顺序不同,他们之间形成重载关系;若完全相同会报错。
且与返回值是没有关系。
函数重载给我们带来好处:函数调用的灵活性,同时一种静态多态。多态:函数的不同实现。
例:
#include
using namespace std;
//C++中的函数重载是发生在同一作用域下的。
int add(int a, int b)
{
return a + b;
}
int add(int a,int b, int c)
{
return a + b + c;
}
string add(string a, string b, string c)
{
return a + b + c;
}
int main()
{
cout << add(10,20) << endl;
cout << add(10,20,30) << endl;
cout << add("xxxxooo","hhhhyyy","gggttt");
return 0;
}
当函数参数默认值与函数重载发生冲突时,一定注意函数调用的参数个数(避免两者之中的冲突时,择优而选)。
C++作用域: 全局作用域,局部作用域,命名空间作用域,类作用域(结构体作用域)
C++的引用就是一种C中的升级版指针。
类型& 引用变量 = 变量
引用并没有开辟新的空间,而是已存在空间变量的别名。
所以他的作用在于函数传参及函数返回值时,可以避免值的拷贝。
int& b = a; //底层的实现:int* const b = &a;
#include
using namespace std;
void swap(int* a, int* b)
{
int temp = *a;
*a = *b;
*b = temp;
}
void swap(int& a,int& b)
{
int temp = a;
a = b;
b = temp;
}
int main()
{
int a = 10;
int& b = a; //底层的实现:int* const b = &a;
//在C++中const修饰的变量必须赋初值。
//引用的语法:类型& 引用变量 = 变量。
cout << &b << endl;
cout << &a << endl;
int x = 20;
int y = 30;
swap(x,y);
cout << "x = " << x <
函数返回值永远不要返回一个局部变量的地址或引用。
关键字new开辟空间。
关键字delete释放空间。
如果是使new在堆上连续开辟空间时,释放空间,则要使用delete[] 来释放空间。
例:
#include
using namespace std;
//自定义Stu类类型。
struct Stu
{
string name;
int age;
};
int main()
{
int* p = new int;
cout << *p << endl;
int* p1 = new int(1000);
cout << *p1 << endl;
int* p2 = new int[10]();
cout << p2[9] << endl;
//连续开辟空间,同时对元素下标0,1,2中的值进行初始化。
int* p3 = new int[10]{1,2,3};//C+11标准下才有这种方式。
//针对于自定义的类类型,如果连续开辟多个空间,一定要使用delete[]来释放。
Stu* stu = new Stu();
//类型后加括号,代表开辟空间同时对结构体中的属性进行初始化。
Stu* stu1 = new Stu[10]();
delete stu;
delete[] stu1;
delete p;
delete p1;
delete []p2;
delete []p3;
return 0;
}