1)C++简介
C++是C语言的扩展,因此C++是C语言的超集,任何有效的C程序都是有效的C++程序,C++可以使用已有的C程序库。
C++在C语言上增加了面向对象编程和泛型编程的支持。
2)可移植性和标准
ANSI在1998年制定出了一个国际标准,不仅描述了已有的C++特性,还对语言进行了扩展,增加了异常、运行阶段类型识别(RTTI)、模板和标准模板库(STL)。
3)面向过程和面向对象
面向过程的核心思想是:功能分解,自顶向下,逐层细化 (程序=数据结构+算法)
面向对象(OOP):使用多个相互独立的代码模块,每个模块提供特定功能,易于开发维护和升级,算法和数据结构看成一个整体,任何对象都有一定的属性和 *** 作。 (程序=对象+对象)
4)面向对象的三大特性:封装、继承、多态。
二、C++对C的扩展1)双冒号:作用域运算符
作用域有就近原则,::为全局作用域,后面加变量名会输出全局变量的值。
2)命名空间namespace使用:namespace主要用来解决命名冲突的问题
命名空间下可以放变量 函数 结构体 类;
命名空间必须定义在全局作用域下;
命名空间可以嵌套命名空间;
命名空间是开放的,可以随时往原来的命名空间中增加内容;
无名/匿名命名空间相当于静态变量,只能在当前文件内使用;
命名空间可以起别名。
3)using声明和using编译指令
写了using声明之后,表明局部变量的命名空间,要避免和局部变量的二义性问题。
如果用using打开多个房间,也要注意二义性的问题。
三、C++对C的增强1)全局变量检测增强
#include
using namespace std;
int a;
int a = 10;
int main() {
return 0;
}
这种全局变量的声明方法在C语言中不会被检测出来,在C++中会被判定为重定义错误。
2)函数检测增强
#include
using namespace std;
int getS(w, h) {
}
void test02() {
getS(10,10,10);
}
int main() {
return 0;
}
这种函数写法,getS没写明返回值以及参数类型,test02中函数调用参数不匹配,在C语言不会被检测出来,C++语言生成失败。
3)类型转换检测增强
#include
using namespace std;
void test03() {
//在C语言中void*可以被任何类型代替
char* p = malloc(sizeof(64)); //malloc返回值为void*
}
int main() {
return 0;
}
void*在C语言中可以被任何类型代替,在C++须进行强转,char* p = (char*)malloc(sizeof(64))。
4)struct增强
#include
using namespace std;
struct Person() {
int age;
void plusAge() {age++;}; //C语言中不能加函数
}
void test04() {
Person p1; //C语言使用时前面必须加struct
p1.age = 10;
p1.plusAge();
cout << p1.age << endl;
}
int main() {
return 0;
}
C语言中struct不能加函数,C++中可以加函数;C语言使用时必须加入struct关键字。
5)bool类型增强
C语言中没有bool类型,C++中提供了bool类型,所有非零值都转换为1。
6)三目运算符增强
void test06() {
int a = 20;
int b = 10;
cout << "ret = " << (a>b?a:b) << endl;
}
直接写(a>b?a:b) = 100,C语言报错,C++将a赋值为10,三目运算符C返回的是数值,C++返回的是变量。C语言中如果要返回变量要加取地址符*(a > b ? &a : &b) = 100。
7)const增强
void test07() {
const int b = 20;
int *p = (int*)&b;
*p = 200;
}
全局区域的const是受到保护的,都不可更改。
C语言中局部变量const修饰的变量会给b分配内存,可以通过指针进行修改,为伪常量,不能用于初始化数组;C++中const不会给b分配内存,不能被修改,为真正常量,可以初始化数组。
C语言中const默认是外部链接,C++中const默认是内部链接。
8)const分配内存的情况
const取地址时会分配一个临时内存,改变的是临时内存的值,而不是常量的。
int tmp = b;
int *p = (int *)&tmp;
如果const前面加了extern作用域设为全局,就会给const分配内存。
用普通变量初始化const变量,会给const分配内存。分配了内存的变量都可以用指针进行修改。
自定义数据类型加const也会分配内存。比如定义结构体Person并声明const Person p1,会给p1分配内存。
9)尽量用const代替define(宏定义)
const有类型,可进行编译器安全类型检查,define没有类型,不可进行类型检查;
const有作用域,define不重视作用域,默认从定义处到文件尾,如果定义在作用域下的有效常量,define就不适用。
四、引用1)引用的基本语法
引用是C++对C的重要扩充,在C/C++中指针的作用是一样的,但是在C++中增加了另外一种函数传递地址的途径,就是引用传递。
void test() {
int a = 20;
//&写在等号左侧表示引用,写在等号右侧表示取地址
int &b = a; //b对a进行引用
b = 100; //此时a也被修改为20
}
引用必须初始化,不能只写int &b;引用初始化后不可修改。
2)对数组建立引用
void test() {
int arr[10];
for(int i = 0; i<10; i++) {
arr[i] = i;
}
//对数组进行引用
int (&pArr[10]) = arr;
//第二种方法给数组起别名
typdef int (array)[10];
array &pArr2 = arr;
}
3)参数的传递方式
参数的传递方式有值传递、地址传递、引用传递。
void mySwap(int a, int b) { //值传递
int tmp = a;
a = b;
b = tmp;
}
void test() {
int a = 10;
int b = 20;
mySwap(a, b);
}
以上方法进行参数传递时,并没有改变test里面a和b的数值,只有mySwap里的数进行了互换,常用于不改变原值,只要返回值的情况,如果要对原来的值进行互换,需要地址传递,或者引用传递。
void mySwap(int *a, int *b) {
int tmp = *a;
*a = *b;
*b = tmp;
}
void test() {
int a = 10;
int b = 20;
mySwap(&a, &b);
}
4)引用的注意事项
引用必须要引一块合法的内存空间,比如 int &a = 10不合法;
不要返回一个局部变量的引用,局部变量在函数结束后生命周期就会结束;
想要返回局部变量的引用需要在局部变量前加上static,将其保存住;
如果函数的返回值是引用,那么这个函数调用可以作为左值;
5)引用的本质
引用的本质在C++内部实现是一个指针常量。
6)指针的引用
利用指针的引用开辟空间。
struct Person() {
int age;
}
void allocatMemory(Person* &p) {
p = (Person*) malloc(sizeof(Person));
p->age = 20;
}
void test() {
Person* p = NULL;
alloctMemory(p);
cout << "P的年龄" << p->age << endl;
}
7)常量引用
const int &ref = 10;
前面加入const后,编译器会处理为const tmp= 10; const int &ref = tmp;此时不会被判定为引用了不合法的内存,此时ref的值可以用过指针进行修改。
int *p = (int*)&ref;
*p = 100;
常量引用的使用场景通常是用来修饰形参为只读。
void showValue(int &val) {
//如果只想显示内容,而不修改内容,就用const修饰
val += 100;
}
void test() {
int a = 10;
showValue(a);
}
PS:
1.阻塞功能:system("pause")
2.返回正常退出:return EXIT_SUCCESS,EXIT_SUCCESS是一个宏,它的值就是0
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)