C++ 和 C的不同之处

在学习C++的过程中,发现了很多C和C++的很细节(真的特别细节)的差别,顺手记录下来,便于对比和加深认识

  • 1 C++的结构可以有成员函数,C的结构只有成员变量
    在这里插入图片描述

类和结构的区别:

  1. C++还是一般只用结构表示纯数据对象,而不会在结构中使用成员函数;
  2. 结构的默认访问类型是public,而类的默认访问类型却是private,所以类中不显式用private也属于私有部分。
  • 2 C++声明一个结构变量可以省略struct关键字,以强调把结构模板当做一个新类型来用,C不允许。
    在这里插入图片描述
  • 3 对于检测和处理内存分配失败(通常是因为内存已被耗尽)的手段不一样:

C++用new运算符分配内存失败则引发异常std::bad_alloc

而C用malloc()函数分配失败只是返回一个空指针,其实C++早期也是像C一样,返回空指针。

  • 4 C++有基于范围的for循环,可以很方便对数组或者容器里的数据做相同操作

  • 5 C++传递函数参数的方式和C略有不同(按值传递的部分是相同的):C语言只能按值传递参数(最多传递一下指针,姑且称之为按指针传递),想要通过函数改变一个变量的值,必须把变量的地址(指针)传给函数,光传变量本身是没用的,因为传变量本身,使用的是变量的副本;但是C++可以直接传入变量名而不是地址,只要把方法的参数声明为引用类型就行,引用类型是C++在C基础上新增的一种类型。

  • 6 函数原型:第一,C的原型是可选的,C++的原型不可或缺;第二,C中函数原型/函数声明的参数括号为空表示先不指出参数,而要在后面定义参数列表,总之不是拍板子说这个函数没有参数,但是 C++的函数原型参数括号如果为空,那就是拍板子告诉编译器,这个函数没有参数!

  • 7 &运算符:C和C++都用&表示地址运算符;但是C++还用它表示引用变量

  • 8 递归: C允许main()函数调用自己;C++不允许main调用自己

  • 9 关键字auto: 在C中是存储类别说明符storage class specifier,但他基本没啥用,具体看这个文章

在C++中不再是存储类别说明符了,但用处很多,比如自动类型推断,函数模板中的后置返回类型等。

  • 10 关键字register:在C和C++中都是存储类别说明符。

C用register建议编译器使用寄存器来存储自动变量,旨在提升访问这个变量的速度,但是编译器是否真的使用寄存器而不是内存中的栈来存,由编译器自己决定。如果经常访问这个变量的话,用register声明一下挺好的,可以加快访问速度。

但是从C++11开始,register就顶替了C的auto的工作,即只是显式说明变量的存储类型是自动的。大概是C++觉得C的auto没啥用,于是给auto新工作(自动类型推断等),看register觉得更没用,毕竟现在硬件和编译器的速度都很快了,于是就让register顶了C的auto的活儿。有一种C++新官上任,把之前C不顺眼或是没必要的地方,统统另做安排的感觉。

总结一下, C的存储类别说明符有
在这里插入图片描述

C++的存储类别说明符比C少了个auto
在这里插入图片描述

  • 11 作用域,或者说全局变量(即外部变量)的使用上:C++大部分都和C一样,但是增加了一点,即C++可以用作用域解析运算符::来指定使用变量的全局版本,就算在函数内部有同名局部变量,::加变量名也是全局版本的值,而不会被局部变量隐藏。示例参见这个博客。C做不到这个。

  • 12 共享数据:C++和C都可以用变量的链接性实现在不同翻译单元的数据共享,但是C++的名称空间还提供了共享数据的另一种方法。所以C++共享数据有两条路可选,C只有一条。

  • 13 C++的const全局变量具有内部链接。C的const全局变量还是外部链接。
    C++和C的普通全局变量都是具有外部链接。

C++的普通全局变量的链接性是外部的,但是const外部变量例外,所以可以放在头文件中,而且包含该头文件的每一个源代码文件都私有了一个该const常量。

我专门写了个C程序来验证,注意要用C编译标准,我用的C11

//main.c
#include <stdio.h>
const int SIZE = 10;//C的const全局变量也是外部链接
void myprint();

int main()
{
    myprint();
    printf("In main(), SIZE = %d\n", SIZE);
    return 0;
}
//file1.c
#include <stdio.h>
extern const int SIZE;//但是一定要做引用声明,不然用不了,编译器会说你没定义变量SIZE

void myprint()
{
    printf("In myprint(), SIZE = %d\n", SIZE);
}

可以看到,file1.c中没有定义式声明SIZE,也没有包含定义了SIZE的头文件,所以是main()函数所在的文件的SIZE被共享了,因此C的const全局变量拥有外部链接

In myprint(), SIZE = 10
In main(), SIZE = 10

把上面代码改为C++的,只是改改输入输出啦

//main.cpp
#include <iostream>
const int SIZE = 10;//C的const全局变量也是外部链接
void myprint();

int main()
{
    myprint();
    std::cout << "In main(), SIZE = " << SIZE << '\n';

    return 0;
}
//file1.cpp
#include <iostream>
extern const int SIZE;//一定要做引用声明,不然用不了,编译器会说你没定义变量SIZE

void myprint()
{
    std::cout << "In myprint(), SIZE = " << SIZE << '\n';
}

报错,即使extern引用声明了的也不行,因为人家只有内部连接
在这里插入图片描述
把代码中的SIZE声明再加一个extern在const前面,就可以强制使得这个const全局变量具有外部链接

extern const int SIZE = 10;

输出

In myprint(), SIZE = 10
In main(), SIZE = 10

当然,证明使用的是同一个变量的最好办法是打印地址,这里就不折腾了,都写好了

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值