C与C++的区别(一)

一、带有默认的函数

        形参变量的默认值从右往左给,例如  int  sum(int  a,int  b=20);

        下面来看两个例子:

    int sum(int a,int b=20);
    int sum(int a,int b=20);   //错误,因为在一个文件中,声明可以无数次,但默认值只能给一次

    int sum(int a,int b=20);
    int sum(int a=10,int b);  //正确,编译器在编译时从上往下走,扫描到b时b已经有默认值了,故此句不受影响

       在编译时,声明不占内存不产生符号,但是定义会。ps:#include<stdio.h>头文件中只有函数的声明,没有定义,定义都在libc.so中。

二、函数重载(函数名相同,参数列表不同)

        C:   根据函数名称来判断是否重定义

        C++:根据函数名称、参数列表来判断是否重定义

        sum函数在.c文件中生成符号    sun  *UND*,在.cpp文件中生成符号    sum_int_int .*text*

       

extern "C"                   //在此大括号中生成的符号是C语言的符号,这是C++独有的语法
{
    int sum(int a,int b)
    {
        return a+b;
    }
}

int sum(int a,int b);
int sum(float a,float b);
int sum(double a,double b);
以上都是可行的。

三、内联函数   inline(在调用点把代码直接展开)

        1)内联函数和宏的区别

             宏:发生在预编译阶段,无类型检查,不安全

             inline:发生在编译阶段,有类型检查,安全

        2)和普通函数的区别

            普通函数调用需要开辟、回退栈帧,内联函数不需要。

            内联函数定义可以写在头文件中,普通函数不能会导致重定义

            普通函数生成的符号是globle的,而内联函数不生成符号

        3)和static函数的区别

            static函数需要开辟、回退栈帧,而内联函数不需要。

            static函数生成的符号是local的,而内联函数不产生符号。

关于什么时候调用内联函数?

函数调用栈帧的开辟回退开销>函数执行的开销

        4)只在release版本生效,debug版本不生效,debug版本中inline函数的调用也需要开辟、回退栈帧

        5)对递归函数的调用不起作用

四、const

    看const修饰什么把类型去掉,只看const右边

    const  int  *p        修饰*p,*p不可修改,即不可解引用

    int  *const  p        修饰p,p的指向不可修改

const int a=10;
int *const p=&a;    //错误     p的指向不可修改,但是可以进行解引用操作,编译器认为你企图修改a的值,故报错
const int *p=&a;    //正确     不能进行解引用操作,数据安全,a的值无法被修改

        1、在C语言中:

         const修饰的量叫常变量,常变量和普通变量唯一区别是:常变量定义以后,不能作为左值使用。

         const不是必须初始化,在整个工程可见。

         const修饰的常变量的值可以被修改

#include<stdio.h>
int main()
{
    const int a=10;
    int *p=(int *)&a;
    *p=20;
    printf("a=%d,b=%d\n",a,b);
    return 0;
}                                        //a=20,b=20

      

     2、在C++中:

        const修饰的量叫常量,可作为左值。

        const的编译规则:所有使用常量名字的地方全部替换成常量的初始值

        const修饰的常变量的值可以被修改

#include<stdio.h>
int main()
{
    const int a=10;
    int *p=(int *)&a;
    *p=20;
    printf("a=%d,b=%d\n",a,b);
    return 0;
}                                        //a=10,b=20

        const必须初始化,生成的符号是local的,只在本文件可见。(如果想让整个工程可见,可以使用extern,告诉编译器将本要生成的local符号改为生成globle符号,例如  extern  const  int  a=10)

        当const引用一个编译阶段不明确的值的时候,常量退化成常变量

int b=20;
const int a=b;

int arr[a]={0};      //错误,常量退化成常变量,常变量不能作为左值


五、引用&

   定义引用的表示方法与定义指针相似,只是用&代替了*。&符号做引用时其后必须紧跟变量名。

   &符号前有类型就是引用,否则就是取地址。

    int a=10;
    int &b=a;        //引用
    int *p=&a;       //对a取地址

     b=20;           //修改a的值
     *p=20;
数组引用实例:
int arr[10]={0};
int **p=&arr;             //错误
int (*p)[10]=&arr;        //正确,等同于int (&p)[10]=arr;   右边的取地址符覆盖前面的指针得到一个引用变量
1)引用必须初始化,初始化的值必须要能够取地址,且一经定义就不能改变。

2)定义引用变量需要开辟内存。

3)访问引用变量时,编译器自动对引用变量进行解引用操作,访问的即是所引用变量的地址。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值