一、对于C语言的增强
1.1、新增命名空间
所谓 namespace,是指标识符的各种可见范围。C++标准程序库中的所有标识符都被定义于一个名为std的namespace中。
如果不使用空间申明std命名空间,则无法直接使用对应里面的方法,如下则会报 cout 和 endl 这两个方法无法找到。
#include <iostream>
int main(void)
{
cout << "hello world" << endl;
return 0;
}
以下是使用命名空间的三种方式
方式一:
直接这两个方法属于std命名空间
#include <iostream>
int main(void)
{
std::cout << "hello world" << std::endl;
return 0;
}
方式二:
直接在开头进行这两个方法的申明,这种方式就是是用到那个就对那个进行申明。
#include <iostream>
using std::cout;
using std::endl;
int main(void)
{
cout << "hello world" << endl;
return 0;
}
方式三:
对于方式三,这种方式我肯经常使用,直接在开头进行std域的所有申明。
#include <iostream>
using namespace std;
int main(void)
{
cout << "hello world" << endl;
return 0;
}
关于定义命名空间使用以下格式:
namespace spaceA{
int a;
}
1.2、bool类型
C++在C语⾔言的基本类型系统之上增加了bool,C++中的bool可取的值只有true和false理论上bool只占⽤用⼀一个字节,如果多个bool变量定义在⼀一起,可能会各占⼀一个bit,这取决于编译器的实现。true代表真值,编译器内部⽤用1来表⽰示 false代表⾮非真值,编译器内部⽤用0来表⽰示bool类型只有true(⾮非0)和false(0)两个值C++编译器会在赋值时将⾮非0值转换为true, 0值转换为false。
#include <iostream>
using namespace std;
int main(void)
{
bool test = true;
cout << "test:" << test << endl;
test = false;
cout << "test:" << test << endl;
test = 100;
cout << "test:" << test << endl;
test = -100;
cout << "test:" << test << endl;
return 0;
}
结果如下:
如果赋值一个非1的数给bool类型,编译器也会将其转换成1。所以对于非零的数,在c++中编译完后都会转换为1,代表真,0则代表假
1.3、三目运算符
在三目运算符中,C语言和C++有点区别,其中C语言返回的是值,C++返回的是变量(引用),所以这就导致在编写代码时候的差异。
在C语言中编写:
#include <stdio.h>
int main(void)
{
int a = 10;
int b = 20;
int c = 0;
c = a < b ? a : b;
return 0;
}
这样编写是完全没有问题,但是如果是反过来着会报错:
(a < b ? a : b) = c;
因为这里涉及到一个左值和右值问题,由于C语言中三目运算符返回的是值,所以无法做左值,只能够做右值。
C++编写:
#include <iostream>
using namespace std;
int main(void)
{
int a = 10;
int b = 20;
int c = 0;
c = a<b ? a:b;
return 0;
}
但是在C++中如果反过来写也是可以的:
(a < b ? a : b) = c;
但是我们知道这个等式最终返回来的是a,所以如果是下面这样写,那么最终会将C的值赋值给a。
#include <iostream>
using namespace std;
int main(void)
{
int a = 10;
int b = 20;
int c = 0;
(a < b ? a : b) = c;
cout << "a=" << a << endl;
return 0;
}
结果如下:
1.4、对于const的增强
const作为一个常量的修饰符,我们都知道他其实只是在c语言中作为一个只读的修饰符,但是他是假常量,我们可以通过指针的方式进行修改。
在C语言中:
#include <stdio.h>
int main(void)
{
const int a = 10;
int *p = &a;
*p = 20;
printf("a=%d\n",a);
}
最终结果如下,作为常量的a却可以修改其中的值,所以说在C语言中const是假的常量,往往只是作为一个修饰符。
在C++中:
如果还是按照之前的那样写,编译也是不会出错,但是我们却无法修改a的值,因为他是真的常量。
#include <iostream>
using namespace std;
int main(void)
{
const int a = 10;
int *p = (int*)&a;
*p = 20;
cout << "a=" << a << endl;
cout << "*p=" << *p << endl;
return 0;
}
其实在C++中,专门开辟一个表来存储const修饰的常量,一个key对应一个value,在编译过程中如果发现有key关键字,则会进行将值替换,所以他是真正的常量,没有任何地址而言。
但是为什么在这里指针取值是可以编译的过去,而且还能运行,那是因为编译器对于这种情况,会临时开辟一个空间,然后将该空间的地址赋值给指针,所以p最终指向的则是编译器临时开辟的空间,所以也能赋值操作。
在这里注意一下const和#define,#define是在预编译的时候无脑替换,而const则是在编译的时候进行替换,所以注意一下。
1.5、枚举类型
枚举类型是另外一种创建常量的方式,在C语言中枚举类型是可以直接赋值数字,可是在C++中必须是它定义的元素,否则会报错,因为这样可以提高代码的可阅读性。
在C语言中:
#include <stdio.h>
enum MyEnum
{
one,
two,
three
};
int main(void)
{
enum MyEnum e1 = one;
e1 = 3;
}
可是这种写法在C++中将会报错,无法通过,以为枚举类型必须是他所定义的元素。
C++方式:
#include <iostream>
using namespace std;
enum MyEnum
{
one,
two,
three
};
int main(void)
{
enum MyEnum e1 = one;
e1 = 3;
return 0;
}
对于下面这个语句:
e1 = 3;
直接提示不能进行int到枚举类型的转换
所以在C++中必须要对枚举类型的变量赋值是必须是枚举类型所定义的元素。
1.6、引用
引用是变量的一个别名,通过引用可以更好的理解这样操作的意义,当然熟悉指针的也可以使用指针。
引用的定义:
int &re = a;
关于引用有四个知识点需要明白:
1 引用没有定义,是一种关系型声明。声明它和原有某一变量(实体)的关系。故 而类型与原型保持一致,且不分配内存。与被引用的变量有相同的地址。
2 声明的时候必须初始化,一经声明,不可变更。
3 可对引用,再次引用。多次引用的结果,是某一变量具有多个别名。
4 &符号前有数据类型时,是引用。其它皆为取地址。
例如经常使用的关于两个值的交换函数
C语言:
#include <stdio.h>
void swap(int *pa, int *pb)
{
int temp;
temp = *pa;
*pa = *pb;
*pb = temp;
}
int main(void)
{
int a = 10;
int b = 20;
swap(&a,&b);
printf("a = %d b=%d\r\n",a,b);
}
运行结果:
在C++中(使用引用的方式):
#include <iostream>
using namespace std;
void my_swap(int &a, int &b)
{
int temp;
temp = a;
a = b;
b = temp;
}
int main(void)
{
int a = 10;
int b = 50;
my_swap(a,b);
cout << "a = " << a << " b = " << b << endl;
return 0;
}
运行结果:
使用引用之后,可以进行变量的传参,因为引用其实就是变量的别名,在运行my_swap传参时候,形参便被实参代替,最终进行交换的则是实参的别名,所以也能达到交换值得目的