
目录
一.C++在工作领域当中的应用

二.C++的第一个程序
如下代码所示为第一个C++程序:
cpp
#include<iostream>
using namespace std;
int main()
{
cout << "Hello World" << endl;
return 0;
}
在这个简单的程序中,我们发现有很多陌生的代码段,如头文件"iostream"、"using namespace std"、"cout"等,这些都是C++所独有的语法形式,接下来我们将会逐一介绍。
三.命名空间
3.1namespace的定义
首先我们来看上述所提到的namespace的含义。
namespace的作用是定义一个命名空间,也就是定义一个域,这个域和全局域相互独立。namespace的定义有以下特点:
1.namespace只能在全局中定义,而且可以嵌套定义;
2.多个文件中出现同名的namespace会被当作是一个namespace;
3.C++的标准库定义在命名空间std中;
示例1:
cpp
#include<iostream>
#include<stdlib.h>
//域
//::域作用限定符
namespace ljt
{
int rand = 1;
}
int a = 0;
int main()
{
int a = 1;
printf("%p\n", rand);
printf("%d\n", ljt::rand);
printf("%d\n", a);
printf("%d\n", ::a);
return 0;
}
示例2:
cpp
#include<iostream>
namespace ljt
{
int rand = 1;
int Add(int x, int y)
{
return x + y;
}
struct Node
{
struct Node* next;
int data;
};
}
int main()
{
printf("%d\n",ljt::Add(5,7));
return 0;
}
示例3:
cpp
//namespace的嵌套
#include<iostream>
namespace ljt
{
namespace pg
{
int rand = 1;
int Add(int x, int y)
{
return x + y;
}
}
namespace xjh
{
int rand = 2;
int Add(int x, int y)
{
return x + y;
}
}
}
int main()
{
printf("%d\n", ljt::pg::rand);
printf("%d\n", ljt::pg::Add(3, 4));
printf("%d\n", ljt::xjh::rand);
printf("%d\n", ljt::xjh::Add(5, 7));
return 0;
}
3.2namespace的使用
1.指定命名空间中特定的成员
cpp
#include<iostream>
using namespace std;
namespace ljt
{
int a = 1;
int b = 2;
}
int main()
{
printf("%d\n", ljt::a);
printf("%d\n", ljt::b);
return 0;
}
2.using展开命名空间中的部分成员
cpp
#include<iostream>
namespace ljt
{
int a = 1;
int b = 2;
}
//展开a
using ljt::a;
int main()
{
printf("%d\n", a);
printf("%d\n", ljt::b);
return 0;
}
3.using展开命名空间中的全部成员
cpp
#include<iostream>
namespace ljt
{
int a = 1;
int b = 2;
int c = 3;
}
using namespace ljt;
int main()
{
printf("%d\n", a);
printf("%d\n", b);
printf("%d\n", c);
return 0;
}
四.C++输入&输出
C++的输入输出函数与C语言的输入输出函数有所不同,在C语言中,我们用到的输入输出函数主要是是printf和scanf,而在C++中,我们用到的输入输出函数主要是cout和cin。
使用C++的输入输出函数需要包含头文件<iostream>。
与C语言的输入输出函数相比,C++的输入输出更方便,主要有以下几点:
1.C++的输入输出函数能自动识别变量的类型,无需再额外添加不同数据类型所对应的占位符;
2.C++的输入输出函数中的变量可以一行写多个;
示例:
cpp
#include<iostream>
using namespace std;
int main()
{
int a = 0;
double b = 1.1;
char c = 'x';
cout << a << ' ' << b << ' ' << c << endl;
cin >> a >> b >> c;
cout << a << ' ' << b << ' ' << c << endl;
return 0;
}
运行结果如图所示:
五.缺省参数
缺省参数也叫作默认参数,指的是在声明或者定义函数时,为函数的参数指定一个缺省值。缺省参数分为全缺省与半缺省。
注意:
1.C++规定半缺省参数必须从右往左连续缺省,间隔不能跳跃;
2.当函数的声明和定义分离时,缺省参数不能再函数的声明和定义中同时出现,规定必须给函数的声明给缺省值;
示例:
cpp
#include <iostream>
using namespace std;
void Func(int a = 0)
{
cout << a << endl;
}
// 全缺省
void Func1(int a = 10, int b = 20, int c = 30)
{
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "c = " << c << endl << endl;
}
// 半缺省
void Func2(int a, int b = 10, int c = 20)
{
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "c = " << c << endl << endl;
}
int main()
{
Func(); // 没有传参时,使用参数的默认值
Func(10); // 传参时,使用指定的实参
Func1();
Func1(1);
Func1(1, 2);
Func1(1, 2, 3);
//Func2();
Func2(100);
Func2(100, 200);
Func2(100, 200, 300);
return 0;
六.函数重载
函数重载指的是再同一作用域中出现同名函数,但是函数参数的个数不同,参数的类型不同,或者参数的顺序不同,这时称为函数重载。
示例:
cpp
#include<iostream>
using namespace std;
// 1、参数类型不同
int Add(int left, int right)
{
cout << "int Add(int left, int right)" << endl;
return left + right;
}
double Add(double left, double right)
{
cout << "double Add(double left, double right)" << endl;
return left + right;
}
void Swap(int* px, int* py)
{}
void Swap(double* px, double* py)
{}
// 2、参数个数不同
void f()
{
cout << "f()" << endl;
}
void f(int a)
{
cout << "f(int a)" << endl;
}
// 3、参数类型顺序不同
void f(int a, char b)
{
cout << "f(int a,char b)" << endl;
}
void f(char b, int a)
{
cout << "f(char b, int a)" << endl;
}
/*下面两个函数构成重载
f()但是调用时,会报错,存在歧义,编译器不知道调用谁*/
namespace bit1
{
void f1()
{
cout << "f()" << endl;
}
}
void f1()
{
cout << "f()" << endl;
}
void f1(int a = 10)
{
cout << "f(int a)" << endl;
}
//返回值不同不能作为重载条件,因为调用时也无法区分
void fxx()
{
}
int fxx()
{
return 0;
}
int main()
{
Add(1, 2);
Add(1.1, 2.2);
f();
f(1);
f(1, 'x');
f('x', 1);
//bit1::f1();
//f1();
f1(1);
fxx();
return 0;
}
七.引用
7.1引用的定义
引用(&)不是新定义一个变量,而是给已存在的变量取一个别名。代码示例如下所示:
cpp
#include<iostream>
using namespace std;
int main()
{
int a = 0;
int& b = a;
int& c = a;
int& d = b;
cout << a << endl;
cout << b << endl;
cout << c << endl;
cout << d << endl;
d++;
cout << a << endl;
cout << b << endl;
cout << c << endl;
cout << d << endl;
return 0;
}
在上述代码中,b和c就是变量a的别名,而d是b的别名,就是变量a的别名的别名,也就是变量a的别名,所以d++后,a、b、c、d的输出结果均为1。
7.2引用的特性
引用具有以下特性:
1.引用在定义时必须进行初始化;
2.一个变量可以有多个引用;
3.引用一旦引用一个实体,就不能引用其它实体;
7.3引用的使用
引用主要用于引用传参和引用做返回值,可以减少拷贝提高效率,在改变引用对象的同时改变被引用对象。
如交换两个数的值,不仅可以用指针传参的方式,也可以用引用传参的方式,且与指针传参相比,引用传参的可读性更高:
cpp
#include<iostream>
using namespace std;
void swap(int& rx, int& ry)
{
int tmp = rx;
rx = ry;
ry = tmp;
}
int main()
{
int a = 3;
int b = 5;
cout << "a = " << a << ' ' << "b = " << b << endl;
swap(a, b);
cout << "a = " << a << ' ' << "b = " << b << endl;
return 0;
}
运行结果如下所示:
7.4const引用
7.4.1权限的放大和缩小
有关权限的放大和缩小的代码如下所示:
cpp
1.权限的放大和缩小
#include<iostream>
using namespace std;
int main()
{
const int a = 10;
const int& ra = a;//权限放大
int b = 20;
const int& rb = b;//权限缩小
b = 30;
cout << b << endl;
cout << rb << endl;
return 0;
}
7.4.2临时对象的创建
临时对象具有常性,所以引用时必须用const进行修饰。如下代码是有关临时对象出现的场景:
cpp
#include<iostream>
using namespace std;
int main()
{
int a = 10;
int b = 20;
const int& rd = (a + b);
double d = 12.34;
const int& ri = d;
return 0;
}
7.5指针和引用的关系
指针和引用具有如下关系:
1.指针和引用相辅相成,功能具有重叠性,但是各有自己的优点,互相不可替代;
2.引用是给已有的变量取别名,不开空间。指针用来存放地址,需要开辟空间;
3.引用在定义时必须进行初始化,指针不必;
4.引用在初始化引用一个对象后,便不能再引用其它对象。指针可以不断改变其指向的对象;
5.引用可以直接访问对象,指针需要解引用才可以访问其指向的对象;
6.sizeof计算不同,引用结果为引用类型的大小,指针结果地址空间所占字节的个数;
7.指针很容易出现野指针和空指针的问题,引用很少出现,所以引用使用起来相对安全一些;
八、inline
inline是C++独有的关键字,用inline修饰的函数叫作内联函数,编译时C++编译器会在调用的地方展开内联函数,所以若inline修饰的函数被编译器当作内联函数进行处理,则该函数没有地址,其它源文件没法调用。
inline对于编译器而言只是一个建议。inline适用于频繁调用的短小函数,对于递归函数,代码相对多一些的函数,加上inline也会被编译器忽略。
C语言实现宏函数也会在预处理时替换展开,但是宏函数的实现比较复杂且很容易出错,且不方便调试,C++设计inline的目的就是替代C的宏函数。宏函数的代码示例如下所示:
cpp
#include<iostream>
using namespace std;
#define ADD(a,b) ((a)+(b))
int main()
{
int x, y;
int ret = ADD(1, 2);//int ret = ((1)+(2))
cout << ret << endl;
cout << ADD(1, 2) << endl;
cout << ADD(1, 2) * 5 << endl;//((1)+(2))*5
cout << ADD(x & y, x | y) << endl;//((x&y)+(x|y))
return 0;
}
九、nullptr
nullptr是独属于C++的空指针,nullptr是一个特殊的关键字,它可以转换为其它任意的指针类型,是用于解决C++中NULL的冲突问题,如下代码所示:
cpp
#include<iostream>
using namespace std;
void fun(int x)
{
cout << "void func1(int x)" << endl;
}
void fun(int* x)
{
cout << "void func2(int* x)" << endl;
}
int main()
{
fun(0);
fun(NULL);//C++中的NULL定义为了整型0
fun(nullptr);
return 0;
}
上述代码的运行结果为:
之所以出现上述运行结果,是因为在C语言中,NULL被转换为(void*)0,它既可以传给int类型的变量,也可以传给int*类型的变量,所以调用函数时会出现冲突;在C++中,NULL被宏定义为整数0,所以它会传给int类型的变量,而不会传给int*类型的变量;而C++的nullptr可以转换为其它任意的指针类型,所以nullptr可以传给int*类型的变量,而无法传给int类型的变量。

