从C到C++的升级(二)

4.内存分配与释放

C语言:

      内存的分配与释放使用malloc free

      有可能会产生野指针(随机指向一块内存的指针),造成内存泄漏

      避免产生野指针的六大习惯:

养成良好的编程习惯

当定义一个没有指向的指针时,将其指向NULL。(NULL代表内存的0地址,并且NULL是不允许做任何操作的)

当想要向指针指向的内存空间操作时,用malloc分配内存。(在堆空间里分配内存)

清空内存中的数据 malloc分配的空间里可能存在垃圾值,因此我们需要清空,可以用到

使用内存

释放内存(free,这时ptr又变成野指针,需再次将它置为空)

C++:

C++中通过new关键字动态内存分配申请,动态内存分配申请是基于类型进行的

变量申请:                              数组申请

Type *pointer = new Type;                   Type *pointer = new Type[N];

通过delete进行内存释放

delete pointer;                             delete [] pointer;

 

new malloc的区别:

new是C++的一部分(运算符),而malloc是C语言调用的一个函数

new是以具体类型为单位进行内存分配的,而malloc是以字节为单位进行分配的

new在申请单各类型变量是可进行初始化,malloc不可以

  例 int * p = new int(5);

 

动态分配二维数组:int (*pp)[2] = new int [2][2];

        三维数组:int (*ppp)[6][6] = new int [6][6][6]

 

拓展:传参规则

#include<stdio.h>
 
voidfunc1(char *ptr)  //一维数组用首元素的地址来接
{
    printf("func1 = %s\n",ptr);
}
voidfunc2(char (*ptr)[100])  //二维数组用一维数组的地址来接
{
    int i;
    for(i = 0; i < 2; i++)
    {
        printf("func2 =%s\n",ptr[i]);
    }
}
voidfunc3(char **ptr)  //一维数组用首元素的地址来接
{
    int i;
    for(i = 0; i < 3; i++)
    {
        printf("func3 =%s\n",ptr[i]);
    }
 
}
intmain()
{
    char ptr[100] = "hello world";
    char str[2][100] = {"hello","world"};
    char *ktr[3] ={"hello1","hello2","hello3"};
    func1(ptr);
    func2(str);
    func3(ktr);
    return 0;
}


 

5.引用与指针

1.引用是给变量起别名

一般格式:类型 &引用名 = 变量名 例:int a = 1; int &b = a;

注意:定义引用时一定要初始化,指名该引用变量的别名

实际应用中,引用一般用作参数传递与返回值

作参数传递时:

例:void swap(int &a, int &b)

引用作为参数对形参的任何操作都能改变相应的实参的数据,又使函数参数的调用显的方便,自然

作返回值时:

可以将函数放在赋值运算符的左边

注意:不能返回对局部变量的引用

#include<iostream>
usingnamespace std;
inttemp = 6;
int& add(int &num)
{
    return temp;
}
intmain()
{
int num = 5;
add(num) = 7;
cout << temp<<endl;
return 0;
}


引用与指针的区别:

引用访问一个变量是直接访问,而指针是间接访问。

引用是一个变量的别名,本身不单独分配自己的内存空间,而指针有自己的内存空间。

引用已经初始化不能再引用其他变量,而指针可以。

尽可能的使用引用,不得已时使用指针。

 

6.函数升级

(1)内联函数:

内联函数与宏函数的区别:

内联函数调用时,要求实参和形参的类型一致,另外内联函数会先对实参表达式进行求值,然后传递给形参;而宏调用只用实参简单地替换形参。

内联函数是在编译的时候,在调用的地方将代码展开的,而宏则是在预处理时进行替换的。

(内联:以空间换时间 宏函数:以时间换空间)

内联函数的使用:

          inlineint max(int a,int b)

          {

               returna>b?a:b;

          }

          #defineMAX(a,b) (a)>(b)?(a):(b)

 

(2)重载函数:

相同的作用域,如果两个函数名称相同,而参数不同,我们把它们称为重载overload

函数重载的条件

函数重载的条件:(函数的返回值不能作为条件)

  ·函数重载不同形式:

        ·形参数量不同

        ·形参类型不同

        ·形参顺序不同

        ·形参数量和形参类型都不同

  ·调用重载函数时,编译器通过检查参数的个数、类型和顺序来确定相应

的被调用函数

 

 namemanagling与extern “C”:

name managling 这里把它翻译为名字改编

·C++为了支持重载,需要进行name managling

 ·extern “C”实现了C与C++混合编程

           #ifdef__cpluscplus

           extern “C”

           {

                #endif

                 ……

                #ifdef__cpluscplus

           }

           #endif

(3)带默认参数的函数:

     ·函数没有声明时,在函数定义中指定形参的默认值

     ·函数既有定义又有声明时,声明时指定后,定义后就不能再指定默认值

     ·默认值的定义必须遵守从右到左的顺序,如果某个形参没有默认值,则

       它左边的参数就不能有默认值

       voidfuncl(int a,double b = 4.5,int c = 3)   //合法

       voidfuncl(int a = 1,double b ,int c = 3)   //不合法

     ·函数调用时,实参与形参按从左到右的顺序进行匹配

 

 7.命名空间-namespace

(1)       命名空间

C语言:

    ·在C语言中只有一个全局作用域

     ·C语言中所有的全局标识符共享一个作用域

         ·标识符之间可能有冲突

C++:

·C++中提出了命名空间的概念

     ·命名空间将全局作用域分成不同的部分

     ·不同命名空间中的标识符可以同名而不会发生冲突

     ·命名空间可以相互嵌套

     ·全局作用域也叫默认命名空间

 

(2)如何定义命名空间

namespaceFirst
{
    int i = 0;
}
namespaceSecond
{
inti = 1;
}
 
usingnamespace First;
 
intmain()
{
cout<<i<<endl;
cout<<Second::i<<endl;
return0;
}


(3)如何使用命名空间

·使用整个命名空间:using namespace name;

·使用命名空间中的变量:using name::variable;

·使用默认命名空间中的变量:  ::variable 

默认情况下可以直接使用

默认命名空间中的所有标识符

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值