c++对c的扩展

1、c++对类型检查比c语言更为严格。如:

\\demo1.c
char* p = malloc(100);           //C语言可以通过,C++报错
char* p = (char*)malloc(100);    //正确

\\demo2.c
const int a = 100;
int *p = &a;                     //C语言警告,C++直接报错
const int *p = &a;               //正确

\\demo3.c
int *p = (int*)&a;               //C语言和C++都正确,但是执行下面两句,C语言输出的是200,
*p = 200;                        //     C++输出的是100, 原因有待深究
printf("a = %d\n", a);

2、const类型c++中必须初始化,c语言中可以不初始化,默认为0, c++中const为真const,不能通过指针修改,c语言中可以

int main(void)
{
    const int a = 1;
    int* p = (int*)&a;
    *p = 100;
    printf("&a = %p, p = %p\n", &a, p);
    printf("a = %d, *p = %d\n", a, *p );
    return 0;
}
/*
此段代码在C语言中是完全正确的,相同的地址,输出相同的值;但是在C++中,奇怪的事情发生了,&a和p的值是相同的,a和*p的值却不同!!!
也就说同一个地址,通过变量和指针取出了不同的值。这主要是因为程序读const的值的时候,不会从内存里面拿,而是从缓存里面拿。
我们应该避免给通过任何途径试图改变const的值,C语言规定了。如果你通过指针修改了一个声明为const的值,那么读取这个值的时候,
结果是"不可预计的",就是说,不同的编译器可能会给出不同的结果,程序员应该避免出现这样的情况
*/

3、c语言中没有bool类型,通过0和非0表示假和真;c++中引入bool型,本质就是枚举,类似于如下定义:

typedef enum {false, true}bool;

4、c++中枚举是真枚举

enum WEEK{SUN, MON, TUE, WED, THU, FIR, SAT};
enum WEEK d1 = 2;  //C语言中合法,C++中是非法的,C++中枚举变量只能取枚举中的值

5、需要char数组的地方尽量用string代替,char数据需要初始化长度,有越界的问题,string完美的解决了这些问题。

6、c++支持函数重载,c语言不支持。参数不同可以构成重载,但是返回值不同不可以。

     重载匹配原则:1严格匹配,找到后调用;2、隐式转换匹配,找到后调用

int func( long a )
{
    return (int)a;
}
int func( double a)
{
    return (int)a;
}
int main(void)
{
    int c = func(1);    // 出现二意性,编译器不知道隐式转换为long还是double
    return 0;
}

7、extern "C" 作用于申明,当调用C语言库时候,需要与C语言保持一致,在C++中需要调用C库的函数申明处加extern "C"

//自己的C语言库,如果需要让C++调用,可以在头文件中如下操作
#ifdef __cplusplus
extern "C" {
#endif

int add( int a, int b );

#ifdef __cplusplus
}
#endif
//如此操作,既可以在C程序中调用, 也可以在C++程序中调用

8、默认参数,1、从右向左,不能跳跃;2、默认参数在申明中指定;3、不能既重载又设置默认参数。不然编译器无法分辨是重载还是默认参数。默认参数可以在申明中指定,也可以在定义中指定,但是强烈推荐申明中指定,因为申明是用户可见的,而且可利用申明来修改默认参数。

//demo.h

int add( int a, int b, int c);
int add( int a = 0, int b = 1, int c = 1 );
int add( int a = 0, int b, int c);         //非法,调用时候add(1,2),编译器不知道怎么分配参数

//只能从右往左,如
int add( int a, int b, int c = 1);
int add( int a, int b = 0, int c = 1);
int add( int a = 1, int b = 2, int c = 3);

//不能既重载,又使用默认参数
int add( int a, int b);
int add( int a, int b, int c = 0);
//此时,当调用add(1,2)时,编译器不知道是调用的哪一个

9、引用,为变量起一个别名,是一个关系型申明。申明时候必须赋值,否则出错,一经申明,不可更改。

int a = 0;
int &ra = a;        //正确方式

int &ra; ra = a;    //非法,第一句就报错,申明了一个引用,但是没有初始化

10、const引用。

//定义
int a = 0;
const int &ra = a;  //合法

int & const a;      //非法,因为引用本身就是一经申明,不可更改的,这种表达没有意义

//const 引用可以是用相关类型的对象或者右值初始化
const int &ra = 2;  //合法,因为有const
int &ra = 2;        //非法

//更神奇的:
double c = 1.23;
int &rc = c;        //非法
const int &rc = c;  //合法, 开辟了新空间
double &rc = c+2;   //非法
const double &rc = c + 2;  //合法, 开辟了新空间

//使用const引用时候,右值需要类型转换或是表达式时,会另外开辟新空间,const修饰的是该空间

11、new用法

int *ip = new int(10);   //初始化一个int空间, 初始值为10
int *ips = new int[10];  //开辟10个int空间

delete ip;
delete[] ips;     

//new 和delete 用法很简单,但是里面的内容却非常非常的多,它染指的是内存分配和释放,足够出一本书了,
//细节东西我们以后再慢慢讲

12、内联函数inline, 优化性能,适用于体积小,频繁调用的函数。避免了调用时的额外开销(主要是入栈和出栈操作),代价是增加了代码段的空间。它比宏函数要好,在C++中建议尽量使用inline代替宏函数。

13、强制类型转换,C++是强类型语言,因此也有强制类型转换函数,如static_cast,dynamic_cast,const_cast,reinterpret_cast等。static_cast是使用最多的,一般用在常用类型的转换;synamic_cast使用在父子类之间的转换;const_cast看名字就是和const类型相关的,它可以用于脱常量;reinterpre_cast即重定义,它可以重新定义一块内存空间的类型。

14、命名空间,用于防止重名,在大型项目中非常有用。分为全局命名空间和局部命名空间,全局命名空间为::。全局变量和全局函数,都属于全局命名空间。命名空间也可以嵌套。

号外:C/C++编译器不会检查数组下标越界。检查下标越界需要额外的程序,影响性能;另外不检查下标越界给程序员更大的空间。

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值