c++入门必备基础


学习内容:

一.命名空间(namespace)

首先了解三个作用域:

(1):局部域

(2):全局域

(3):命名空间域

命名空间是一种避免命名冲突的机制,它是隐藏在全局域里的单独的一种作用域,在该空间内可以定义函数、变量、类型、宏定义等,如:

namespace bit1

{

int rand=1;

void fun();

};

那么如何使用命名空间里的内容呢,有三种方式:(1):指定域(2):将域全部展开;(3):指定展开域的某一部分

分别对应这三个例子:

(1):bit1::rand /bit1::fun()/struct bit1::student;

(2)using namespace bit1;

(3):using bit1::rand;

注意:1.全部展开可能导致命名隔离失效,要慎用!一般在日常做题时就用,做项目时不用

2.命名空间的展开不是将其内的变量放在了全局域,而是贴上了标签,正常编译器都是先查找局部域再查找全局域,展开命名空间后还可以查找命名空间域。

二.函数重载和缺省参数

(1)函数重载是什么:在同一个作用域内,函数的名字相同,但是它们的参数列表(形参的类型、个数、类型顺序)不同,从而使得它们可以共存。

(2)为什么c语言不支持重载,cpp支持?

原因:在链接过程中,c语言是通过函数名去进行查找,而cpp是根据修饰后的函数名进行查找,具体的修饰由编译环境决定,修饰后的函数名具有唯一性

(3)示例:

void fun(int a,char c)       void fun(char a,int c)      void fun(int a,int c)    

{                                           {

//……                                  }

}

这三个都是构成函数重载,可以在同一个域内共存,但是调用时可能会出现“调用歧义”,比如

fun(1,'a'),fun('a',1),fun('a','a');当只有前两个时,可以正常运行,但对于第三个调用,就会产生“三个函数都可以调用,不知道调用谁”的歧义

(4)缺省参数

缺省参数就是在函数形参赋上一个缺省值(默认值),那么该参数在调用时就可以不传递实参,但要注意缺省值必须从右往左给,如void fun(int a,int b=1,int c=2);调用时,a必须传值,b和c如果不传,则默认为1和2.

(5)缺省参数不影响函数重载

例如 void fun(int a=1)和void fun()就构成重载,但是如果调用f()就会有歧义。

警示:

1.重载必须是在同一个域内

2.在同一个域且函数名相同时,参数列表就决定是否重载

3.调用函数时,编译器会根据修饰后的函数名去各域进行查找,如果有多个函数都可以调用,就会产生歧义

4.多个重载的函数在调用时可能会产生歧义

三.引用(&)

1.在c语言中我们学过如果有int *p=&a,那么*p就是a的别名,其实引用也是“起别名”的一种操作,例如,我们想给int a起别名,就可以int& p=a,给int*a起名就是int*& p=a;

2.引用某些时候可以取代指针的操作,例如交换两个数的函数,我们之前要在形参上加指针才可以,现在把形参可以改成引用类型,如

void swap(int& a, int& b)

{

 int tmp = a;

 a = b;

 b = tmp;

}

这样a,b就是对应实参的别名,也就能改变实参的值了。

3.引用的特性

(1):定义时必须初始化(int& p;p=a不可取);

(2):同一个变量可以有多个引用别名(int&p=a,int&b=a可以);

(3):引用一个实体后不能再引用其他实体(不能作为多个变量的别名)(int& p=a,p=b不可取);

4.引用时要注意权限“可小不可大”

(1)对于const int *a=&b;int& p=a可以吗?不可以

原因是原本*a由于const的修饰,是不可以修改的,但是*p是可以改变的,这无疑扩大了使用权限,所以应该用const int*& p=a才可以

(2)对于int *a=&b,const int*& p=a;是可以的。

因为原来的*a就是可读可改的,而*p加上const后不能修改,这是权限的缩小,是被允许的,只是不能通过别名p来改变*a了而已

5.传值、传引用效率比较

   以值为参数或者返回类型,在传参和返回期间,函数不会直接传递实参或者将变量本身直接返回,而是传递实参或者返回变量的一份临时拷贝,因此用值作为参数或者返回类型,效率非常低下,尤其是当参数或者返回值类型很大时效率更低。

6.引用和指针的区别

引用和指针的不同点:

(1):概念上,引用定义一个变量的别名,指针存储一个变量的地址。

(2):语法上,引用不开空间,指针需要开空间。在语法概念上引用就是一个别名,没有独立空间,和其引用实体共用同一块空间,在底层实现上实际是有空间的,因为引用是按照指针方式来实现的。

(3):引用在定义时必须初始化,指针没有要求

(4):没有NULL(相对来讲的,其实可以有,但用的时候会报错),但有NULL指针

(5):在sizeof()中含义不同:引用结果为引用实体类型的大小,但指针始终是地址空间所占字节个数(32位平台下是4个字节)

(6):引用自加即引用实体的加一,指针自加即指针向后偏移一个类型的大小。

(7):有多级指针,但没有多级引用

(8):访问实体方式不同,指针需要解引用,引用编译器自己处理

(9):引用比指针使用起来相对安全

注意:

1.对于有const的变量,指针的使用也要遵循权限规则   

2.在c语言中,对权限的要求并不严格,因此会出现明明用const修饰了int a,但是int *p=&a,还可以通过*p的改变来“钻空子”,但这在c++是不允许的,必须在int*p的前面加const。

3.double d=1.2;int& p=d不可取,int x=0,y=1;int& p=x+y不可取,这是因为“隐式类型转换”和表达式运算都会产生临时变量,临时变量具有“常性”,不可被修改,上式都扩大了权限,应该加const

四.内联函数

1.概念:以inline修饰的函数叫做内联函数,编译时编译器会在调用函数的地方展开,没有函数调用建立栈帧的开销,能提升程序运行的效率、

2.特性:

(1):inline是一种以空间换时间的做法,在编译阶段,会用函数体代替函数调用,缺陷:可能会使目标文件变大,优势:少了调用开销,提高程序运行效率。

(2):inline对于编译器而言只是一个建议,不同编译器对于Inline实现机制不同,一般建议:将函数规模较小、不是递归、且频繁调用的函数采用inline修饰,否则编译器会忽略inline特性。

(3):inline不建议声明和定义分离(这里指的是声明和定义跨了文件),分离会导致链接错误。因为inline被展开,就没有函数地址了,链接就会找不到。

(4):inline在声明和定义中不能同时出现,只要有一个就行,一般在声明中体现

【面试题】

 宏的优缺点?

 优点:

 1.增强代码的复用性。

 2.提高性能。

 缺点:

 1.不方便调试宏。(因为预编译阶段进行了替换) 

 2.导致代码可读性差,可维护性差,容易误用。 

 3.没有类型安全的检查 。

 C++有哪些技术替代宏?

1. 常量定义 换用const enum

2. 短小函数定义 换用内联函数 

五.auto关键字

1.含义

auto作为一个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期推导而得。(auto实际上就是自动化类型,会根据你的初始值来推导出相应的类型)

注意:使用auto定义变量必须对其进行初始化,在编译阶段编译器需要根据初始化表达式来推导实际类型,因此auto并非是一种“类型”的声明,而是一个类型声明时的“占位符”“转换说明”,编译器会在编译时将auto转换为实际类型。

2.使用细则:

(1):auto与指针、引用的结合使用:

int x = 10;

    auto a = &x;

    auto* b = &x;

    auto& c = x;

用auto声明指针类型时,auto和auto*没有区别,但声明引用类型时必须加&;

(2). 在同一行定义多个变量

当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错,因为编译

器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量。

3.auto不能推导的场景

(1).不能作为函数的参数

(2)auto不能直接用来声明数组

4.范围for语法及其使用条件

  对于一个有范围的集合而言,for循环后的括号由冒号“ :”分为两部分:第一部分是范

围内用于迭代的变量,第二部分则表示被迭代的范围。

代码:

 int array[] = { 1, 2, 3, 4, 5 };

 for(auto& e : array)

     e *= 2;

 

 for(auto e : array)//将数组array中的元素从头到尾挨个赋给中间变量e,自动递增,判断结束,达到遍历的效果

     cout << e << " ";

使用条件:

.循环的范围必须确定

注意:以下代码就有问题,因为for的范围不确定

void TestFor(int array[])

{

    for(auto& e : array)

        cout<< e <<endl;

}

六。关于c++的空指针

注意:

1. 在使用nullptr表示指针空值时,不需要包含头文件,因为nullptr是C++11作为新关键字引入

2. 在C++11中,sizeof(nullptr) 与 sizeof((void*)0)所占的字节数相同。

3. 为了提高代码的健壮性,在后续表示指针空值时建议最好使用nullptr。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值