三、C++对C的增强

一、全局变量检索增强

// C

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>

// 全局变量检索增强, 在全局变量中是可以的,但是在局部变量中会重定义
int a;
int a = 20;

int main()
{

    return 0;
}
// C++

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
// 全局变量检索增强, 在C语言中全局变量中是可以的重定义的,但是在C++中编译就会报错
int a;
int a = 20;

int main()
{

    return 0;
}

 

二、函数检索增强

// C

// 函数检索增强, 在C语言中 参数类型,返回值都没有, 传参个数也不对test02, 但是可以编译成功,运行成功,但是有警告
int getRectS(w, h)  // 获取矩形面积
{

}

void test02()
{
    getRectS(10, 10, 10);
}
// C++

// 函数检索增强, 在C++中会报错, 参数类型,返回值都没有,应该如下修改才可以, test02传参的个数也不对,C++也会报错
//int getRectS(w, h)  // 
//{

//}
int getRectS(int w, int h)  // 获取矩形面积
{
    return w*h;
}
//void test02()
//{
//    getRectS(10, 10, 10);
//}

 

三、类型转换增强

// C

// 类型转换中增强, 在C语言中 malloc返回值是 void, 但是编译过程不会报错
void test03()
{
    char* p = malloc(sizeof(int));  
}
//C++

// 类型转换中增强, 在C++中必须要强写 char *
void test03()
{
    char* p = (char *)malloc(sizeof(int));
}

四、struct增强

// C

// struct增强, C语言中struct不可以加函数, 结构体在使用时 必须加入 struct 关键字
struct Person
{
    int age;
    // void plusAge();  // C语言中struct不可以加函数
};

void test04()
{
    struct Person p1 = {0}; //  struct必须要 

}
// C++

// struct增强, C++中struct可以加函数, 使用的试过struct可以不要 
struct Person
{
    int age;
    void plusAge()
    {
        age++;
    };  // C++中struct可以加函数
};

void test04()
{
    Person p1 = { 0 }; //  struct可以不要 
    p1.age = 10;
    p1.plusAge();
    cout << "age = " << p1.age << endl; // age = 11
}

 

五、bool 类型

// C

// bool 类型 C语言中没有 bool 类型
// C++

// bool 类型 只有真或假,也就是 0, 1
bool flag = true;
void test05()
{
    cout << flag << endl;  // 1
}

 

六、三目运算符增强

// C

// C语言中返回的是 值
void test06()
{
    int a = 10;
    int b = 20;
    printf("%d\n", a > b?a:b); // 20

    // (a > b ? a : b) = 100; C语言这样写报错, C语言中返回的是 值
    *(a > b ? &a : &b) = 100;  // C中模仿C++的写法
}
// C++

// C++返回的是变量
void test06()
{
    int a = 10;
    int b = 20;
    cout << "ret = " << (a > b ? a : b) << endl; // ret = 20
    (a > b ? a : b) = 100;  // b = 100, C++返回的是变量, 返回的是 b, 然后将 100 赋值 给 b
    cout <<"a = "<< a <<"  b = "<< b << endl;  // a = 10  b = 100
}

七、const增强

     const int f = 10;
     int *p = (int *)&f;
     *p = 200; 

C 中, const修饰的变量是伪常量, 编译器是会分配内存的。
     
C++ 中, const不会分配内存,试讲 f 和 10 放在 符号表中。

在C++中能改变 *p 是因为编译器临时开辟了一块空间, 在C++操作中相当于如下操作:
    int tmp = f;
    int *p = (int *)&tmp;  // *p 指向的是临时的那块空间, 但是临时空间是看不到的。

在 C 语言中 const 默认是外部变量, 在C++中默认是内部变量
// C

// const 增强
const int e = 10;
void test07()
{
    // e = 100;  // 全局的 e 不允许被修改, 指针也改不了
    const int f = 10;  // 伪常量
    // f = 20;   // 局部的 f 不允许直接修改
    int *p = &f; // 局部的 f 可以通过指针修改
    *p = 200;
    printf("*p = %d, f = %d\n",*p,  f); // *p = 200, f = 200

    //int arr[f]; // 这样会报错,不可以这样初始化数组
}
// C++

// const 增强
const int e = 10;
void test07()
{
    // e = 100;  // 全局的 e 不允许被修改, 指针也改不了
    const int f = 10;  //  真正的常量, 改不了的
    // f = 20;   // 局部的 f 不允许直接修改
    int *p = (int *)&f; // 局部的 f 不会被改变, *p是可以改变的
    *p = 200;
    cout << "*p = " << *p << "  f = " << f << endl; // *p = 200  f = 10

    int arr[f]; // C++ 这样是可以初始化数组
}

八、C++中的 const与分配内存

从 4.7 中知道 const修饰的变量 在某些情况下是可以修改的。只要分配了内存就可以修改,如果没有分配内存就不会被修改。

8.1 C、C++中const 的外部链接与内部链接

// C 语言中 const是默认是外部链接
// C++ 中, const 默认是内部链接
// C 语言中 const是默认是外部链接

// test.c
const int A = 10;

// main.c
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>

int main()
{
    extern const int A;
    printf("A = %d\n", A); // A = 10
    return 0;
}
// C++ 中, const 默认是内部链接

// test,cpp
const int B = 10;

// main.cpp
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;

int main()
{
    extern const int B; // 报错, 没有外部符号 int const B
    cout << "B = " << B << endl;
    return 0;
}

// 想要能找到, 需要在test.cpp 写成
// extern const int B = 10;

8.2 const 与分配内存

只要分配了内存, 都可以通过指针来改一些数据

8.2.1 取地址会给 const 分配临时内存

#define _CRT_SECURE_NO_WARNINGS 1

#include<iostream>    
using namespace std; 

// 1. 取地址会分配临时内存
void test01()
{
    const int a = 10;
    int *p = (int *)&a; // C++中必须要有 int *强制转换, 否则会报错, 会分配内存
    *p = 20;
    cout << "*p = " << *p << endl;   // *p = 20
    cout << "a = " << a << endl;     // a = 10

}

int main()
{
    
    test01();
    return EXIT_SUCCESS;              
}

8.2.2 变量初始化 const 的变量会分配内存

// 用变量初始化 const 的变量会分配内存

void test02()
{
    int b = 10;
    const int c = b;  // 会分配内存, 但是 const int a = 10; 就不会分配内存
    int *p = (int *)&c;
    *p = 20;
    cout << "*p = " << *p << endl;   // *p = 20
    cout << "c = " << c << endl;     // c = 20
}

8.2.3 自定义数据类型加 const 会分配内存

struct Person
{
    string name;
    int age;
};

void test03()
{
    const Person p1;
    // p1.name = "wangyong";  // 报错, const不能直接这样修改
    Person *p = (Person *)&p1;
    p->name = "wangyong";
    (*p).age = 27;
    cout << "name = " << p1.name << endl;   // name = "wangyong"
    cout << "age = " << p1.age << endl;     //  age = 27

}

8.3 尽量用 const 替换 #define

#define MAX 1024;

我们定义的宏 MAX 从来没有被编译器看到过, 因为预处理阶段, 所有的 MAX 已经被调换成了 1024

// const 与 # define 区别
1. const 有类型, 可进行编译器类型安全检查, #define无类型,不可进行类型检查
2. const 有作用域, 而 #define 不重视作用域, 默认定义处到文件结尾, 如果定义在指定作用域下有小的常量, 那么#define就不能用

 

posted on 2022-01-15 17:15  软饭攻城狮  阅读(52)  评论(0编辑  收藏  举报

导航