C与C++之间的语法差异

作为以C为基础的语言,C++在基本的语法方面与C大体相同,但是又在部分地方存在一些区别,所以写下本文章作为记录。


1、头文件

C与C++都使用#include引入头文件,但是对文件名的操作存在一些不同,C中使用带后缀.h的完整头文件名,但C++不需要加入后缀,例如:

// C风格
#include <stdio.h>
// C++风格
#include <iostream>

除此之外,在C++中想使用C函数库,一般使用重写过的以c开头的库而不是原版库,其更加符合C++的标准,例如在C++中使用stdio.h

#include <cstdio>

2、函数原型及定义

2.1 未命名参数

C语言中不允许在函数定义中使用未命名的参数,但是在C++中可以存在未命名参数。这种参数存在的目的是“保留参数列表中的位置”,这样可以在将来使用这个参数,而不必修改函数代码。

2.2 空参数列表

C语言中一个函数原型若没有任何参数,则代表其拥有可变参数列表,而C++中则代表该函数没有参数。C中只有指定void参数才表示0个参数,例如:

// 可变数据参数
int function();
// 空参数
int function(void);

3、定义变量

C和C++在定义变量时有明显的区别,C与很多传统过程类型语言一样,都是在作用域的开始处强制定义所有变量(不过在C99标准中已经支持任意位置定义变量),而C++则是没有这个限制,典型的用例如下:

// C风格
int i;
for(i=0; i++; i<10);
// C++风格
for(int i=0; i++; i<10);

4、类型转换

除了使用(type)的转换方式外,C++加入了另外一种显示转换语法,以防止强制转换引入的漏洞。

4.1 静态转换

静态转换static_cast<type>适用于良性的定义清晰的转换,比如非强制变换、窄化变换、void*的强制变换(C++不允许强制转换void*为其他类型,必须使用显示转换),隐式类型变换和类层次的静态定位,例如:

// 非强制变换
int i = 10;
long l = static_cast<long>(i);
// 窄化变换
l = static_cast<int>(i);
// void*的强制变换
void* p = &i;
int* ip = static_cast<int*>(p);

4.2 常量转换

常量转换const_cast<type>用于去除变量的const或者volatile属性,这是其唯一的用法,且转换过程如果涉及其他变换则很可能报错:

const int i = 10;
// 对i取地址获得指向const int的指针,需要转换才可以赋值给int类型指针
int *ip = const_cast<int*>(&i);

4.3 重解释转换

重解释转换reinterpret_cast<type>非常不安全,这种操作是将被操作对象看作完全不同的另一种对象,它剥去了对象的外在结构,是低级的位操作,既是C语言灵活的体现也是名声不佳的原因之一。如下代码,将结构体X转换为整形指针,并依次为其赋值。

const int size = 10;

struct X{
    int array[size];
};

int main(){
    X x;
    int *xp = reinterpret_cast<int*>(&x);
	for(int *i = xp; i < xp + size; i++){
	    *i = 0;
	}
}

通过重解释转换的方式给对象x中的整形数据都赋予了初值0,与遍历数组并赋值效果一样,但使用reinterpret_cast<type>非常不理智且不方便,仅在必须场合才考虑使用。

5、访问控制

C++中引入了public、private、和protected三个关键字用于在结构体中控制不同成员的可访问性。如果没有使用关键字进行约束,则C与C++结构体中的成员都是默认为public属性,而C++又进一步使用了class关键字,一个class与struct只有一处不同,就是默认的成员访问属性,class默认为private而,struct默认为public,这一点也比较容易理解,class的使用目之一的就是对于成员和成员之上绑定的操作对于外界的隔离,默认为public反而会与该理念相悖。

posted @ 2023-07-01 20:53  夏夜大三角  阅读(220)  评论(0)    收藏  举报