(黑马C++)L01 C++概述

(黑马C++)L01 C++概述,第1张

一、C++概述

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

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/2991547.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-09-23
下一篇 2022-09-23

发表评论

登录后才能评论

评论列表(0条)

保存