c++对c的优化

c++的诞生,肩挑兼容c语言所有特性的担子,所以c++继承了c语言的的所有特性,但是在c的基础上提供了更多的语法和特性。c++既以c语言为基础,又支持面向对象,且具有类型加强、函数加强、异常处理等特点。听了狄泰软件唐老师的课程,现总结c++对c语言的升级。

1. register关键字

c语言中,register关键字请求(只是请求,编译器完全可以拒绝)编译器将局部变量存储于寄存器中,在c++中依然支持register关键字,c语言中无法获取register变量的地址,但是c++可以,说明c++编译器有自己对该关键字的优化方式,随着编译器的迭代,有些变量即使程序员没有指定为register,也可能会被编译器优化成register。c++的register关键字,仅仅只是为了兼容c语言,c++编译器发现程序中需要取register变量的地址时,register对变量的声明变得无效。

2. 重复定义多个同名的全局变量

在c语言中,重复定义多个同名的全局变量是合法的,在c++中不允许定义多个同名的全局变量。

#include <stdio.h>

int gloabA;
int gloabA;

int main(void)
{
    //...
}

将上面代码编辑.c和.cpp文件,分别用gcc和g++去编译,结果.c文件编译通过,.cpp则报错。

3. struct关键字

c语言中的struct定义了一组变量的集合,struct定义的标识符并不是一种新的类型,用typedef可以起到类型定义一种新的类型的效果,而在c++中,struct用于定义一种全新的类型,

//.c使用struct
struct _t{
    int a;
    char c;
};

int main(void)
{
    sttuct _t t;
    return 0;
}
//.cpp使用struct
struct _t{
    int a;
    char c;
};

int main(void)
{
    _t t;
    return 0;
}

4. c++不支持默认声明

c++中所有的标识符都必须显示的声明类型,c语言中的默认类型在c++中不合法的,

f(i)
{
    printf("i = %d\n", i);
}

g()
{
    return 0;
}

在c语言中,int f()表示返回值为int,接受任意参数的函数,f(void)表示返回值为int的无参函数。在c++中,int f()和int f(void)具有相同意义,表示返回值为int的无参函数。

5. const关键字

c语言中,const修饰的变量不是真的常量,它只是告诉编译器不能出现在赋值符号的左边。c语言中的const使得变量具有只读属性,const将具有全局生命周期的变量存储于只读存储区。const不能定义真正意义上的常量。在c语言中真正意义上的常量只有枚举类型。
同样一份代码,编辑成.c和.cpp文件:

int main(void)
{
    const int a = 0;
    int *p = NULL;

    p = (int *)&a;
    *p = 5;
    printf("a = %d, *p = %d\n", a, *p);

    return 0;
}

.c的运行结果:
这里写图片描述
.cpp的运行结果:
这里写图片描述
语言的修改const变量起到效果,对cpp不起效果。c++在c语言的基础上对const进行了进化处理,当碰见const声明时在符号表中放入该const常量,编译过程中若发现使用常量则直接以符号表中的值替换,编译过程中若发现对const常量使用extern、对const常量使用&操作符,则给对应的常量分配存储空间。强调,c++编译器虽然可能为const常量分配空间,但不会使用其存储空间的值,c++中在栈上强调,c++编译器虽然可能为const常量分配空间,但不会使用其存储空间的值,c++中在栈上分配的const变量空间是无作用的,只是为了兼容c语言罢了。
c++中的const常量类似宏定义,

#define c 5 /* 约等于 */ const  int c = 5;

但是宏定义由预处理器处理,只是单纯的文本替换,而const常量是由编译器处理,编译器对const常量会进行类型检查和作用域检查,
测试程序1:

int main(void)
{
    const int A = 5;
    const int B = 6;
    int array[A + B] = {};
    return 0;
}

c语言运行结果:
这里写图片描述

cpp运行结果:
这里写图片描述

对于c文件来说,const修饰的变量还是变量,只不过是具有只读属性,所以编译器在编译阶段并不能确定它要分配多大的数组空间,所以直接报错。
对于cpp文件来讲,const修饰的变量是真正意义上的常量,该常量会放入符号表中,所以在编译阶段,A和B会的值会被从符号表中取出,类似于宏替换的效果,但是要比宏替换安全得多,所以编译通过。
c/c++的宏定义只是单纯的文本替换,它不做作用域、类型等的检查,下面程序可以验证作用域不做检查的结论:

int fun()
{
    #define A 5
}

int my_func()
{
    printf("A = %d\n", A);
}
int main(void)
{
    return 0;
}

6. 布尔(bool)类型

c语言中并不存在bool类型,而是使用int型变量来充当,其值等于0表示为假,非0则表示为真。c++则引入bool类型,c++中的bool可取的值只有true和false,理论上bool只占用一个字节。true代表真值,编译器内部用1来表示;false代表非真值,编译器内部用0来表示。c++编译器会将非0值转换为true,0值转换为false。

7. 三目运算符

测试程序:

int main()
{
    int a = 1;
    int b = 2;

    (a < b ? a : b) = 3;
    printf("a = %d, b = %d\n", a, b);

    return 0;
}

对于c语言来说,运行结果:
这里写图片描述
三目运算符在c语言中是不可作为左值使用,因为它返回的是一个值而非变量。同样的程序在cpp就能编译通过:
这里写图片描述
cpp中,三目运算符返回的是表达式,所以返回的是a的引用(引用是c++才有的概念),对变量a的引用赋值为3自然可以。c++中的三目运算符可直接返回变量本身,所以它既可以作为右值使用,又可以作为左值使用。但是要注意,三目运算符中可能返回的值如果有一个是常量值,那么就不能作为左值使用。
如下:

int a = 1;
int b = 2;

(a < b ? a : 5) = 3;
printf("a = %d, b = %d\n", a, b);

同样是编辑成cpp文件,编译时报错:
这里写图片描述
这个错误跟刚才的c语言文件是一样的,验证了上面的说法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值