C++基础

C++基础

命名空间

  • 命名空间可以定义变量和函数

  • 命名空间可以嵌套

  • 使用

    1.不展开

    namespace N
    {
        int a=10;
    }
    int main()
    {
        printf("%d",N::a);
    }
    

    2.单独展开

    using N::a;
    int main()
    {
    	printf("%d",a);
    }
    

    3.整个展开

    using namespace N;
    int main()
    {
    	printf("%d",a);
    }
    
#include<iostream>
using namespace std;//C++中所有东西都在namespace中
int main()
{
    cout<<"hello world"<<endl;
    std::cout<<"hello world"<<std::endl;//单独展开(同上讲解) 
    return 0;
}

【std日常联系,图方便,全展开】

【std项目当中,可展开部分】

缺省参数

#include<iostream>
using namespace std;
void Func(int a=0)//缺省参数,若无传参,即用a=0(备胎)
{
    cout<<a<<endl;
}
int main()
{
    Func(10);//打印10
    Func();//答应0;
    return 0;
}
  • 缺省参数-------备胎参数

全缺省(缺省全部参数)

void Func(int a=1,int b=2,int c=3)
{
    cout<<"a="<<a<<endl;
    cout<<"b="<<b<<endl;
    cout<<"c="<<c<<endl;
}
int main()
{
    Func();
    Func(4);
    Func(4,5);
    Func(4,5,6);
}

半缺省(缺省部分参数)必须从右往左连续缺省

(调用从左往右依次调用)

void Func(int a,int b=2,int c=3)
{
    cout<<"a="<<a<<endl;
    cout<<"b="<<b<<endl;
    cout<<"c="<<c<<endl;
}
int main()
{
    //Func();//a无参数,不可取
    Func(4);
    Func(4,5);
    Func(4,5,6);
    //Func(1,,3);//不可
    //调用从左往右依次调用
}

函数重载

一个函数可能会有多个意义,或多种调用方式(一词多义)

include<iostream>
using namespace std;
int Add(int a,int b)
{
    return a+b;
}
int Add(double a,double b)
{
    return a+b;
}
int Add(long a,long b)
{
    return a+b;
}
int main()
{
    return 0;
}

函数名相同,参数不同(返回值不同不构成重载int Func()–void Func() )

  • 类型不同

    Func(int a,int b)
    Func(double a,double b)
    
  • 个数不同

    Func(int a,int b)
    Func(int a)
    Func()
    
  • 顺序不同

    Func(double a,int b)
    Func(int a,double b)
    

返回值没有要求

调用时自动识别

面试二问

  1. 什么是函数重载
  2. C++是如何支持函数重载的?C语言为什么不支持?
list.h list.c test.c
  1. 预处理 -->展开头文件,宏替换,去注释,条件编译

    list.i test.i
    
  2. 编译 -->处理语法错误,将代码转化为汇编语言

    list.h test.h
    
  3. 汇编 -->将生成的汇编代码转化为二进制的机器指令

    list.o test.o
    
  4. 链接 --> 将多个源文件链接起来

    test.c
    void list_push_back(int x);
    void add(int i,int j);
    int main()
    {
     list_push_back(1);
     return 0;
    }
    ->test.o
    call list_push_back(?)
    //只有声明,没有定义,没有地址
    //链接时,这里的问号表明在编译时只有声明,没有定义,所以无法找到他的地址,表示链接时,到其他目标文件符号表中去找到这个函数的地址
    //只有声明,没有定义,会出现链接错误
    符号表:
    main:0x31141321
    
    list.c
    void list_push_back(int x);
    void add(int i,int j);
    void list_push_back(int x)
    {
     printf("%d\n",x);
    }
    void add(int i,int j)
    {}
    ->list.o
    list_push_back()
    {
     .....
    }
    符号表:
    list_push_back:0x31144332
    add:0x31144332
    

编译时函数名跟参数关联起来(Z3是前缀)

extern “C”

C++实现 编译成动态库或者静态库

void*tcmalloc(size_t n)

C++ 程序调用可以 C程序调用也许不可以

c++

call tcmalloc(?)

c

call tcmalloc(?)

要求C和C++程序都可以使用C++编译成的动态库或静态库

extern "C" void* tcmalloc(size_t n)
//按c的修饰规则去调用

引用

#include<iostream>
using namespace std;
int main()
{
	int a=1;
	int &ra=a;//ra是a的引用,给a起了一个别名ra
}
  • 共用一块空间,不开辟新空间
  • 必须在定义的时候进行初始化(别名)
  • 引用只能引用一个实体
#include<iostream>
using namespace std;
int main()
{
	const int a=1;
	int &ra=a;//权限放大,不可取
}
  • 权限可以放大,不可以缩小
#include<iostream>
using namespace std;
int main()
{
	int a=1;
    double b=a//隐式类型转换,转换的时候会产生一个临时变量,临时变量具有常性(相当于const修饰)
	double &ra=a;//不可以
    const double &ra=a;//可以
}
  • 赋值之间没有权限变大或缩小的关系,引用才有

  • 如果返回变量是一个局部变量,引用返回时是不安全的

    总结:一个函数要使用引用返回,返回变量出了作用域还存在,就可以使用引用返回,否则就不安全(全局变量,静态变量适合引用返回)

那么函数适应引用返回的好处是什么

  1. 少创建一个临时变量,提高程序运行效率
  2. 待定,我相信你会回来的

引用的目的

  1. 做输出型参数
  2. 提高传递效率
#include<iostream>
using namespace std;
int main()
{
	int a=10;
	int &b=a;
	int *p=&a;
	return 0;
}

指针与引用的区别

  1. 在概念上b就是a的别名,不开辟新的空间,就是一个别名,在底层实现上,是用指针的方法去实现的,指针在概念上是地址
  2. 引用必须初始化,指针不用(建议给NULL)
  3. 引用引用一个实体后,不能引用其他实体,指针可以在任何时候指向任何一个同类型实体
  4. 没有NULL引用,但有NULL指针
  5. 在sizeof中含义不同,引用结果为引用类型的大小,指针是地址空间所占的字节数
  6. 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小
  7. 有多级指针,但没有多级引用
  8. 访问实体方式不同,指针需要显式解引用,引用编译器自己处理
  9. 引用比指针使用起来安全

内联函数

频繁调用函数(调用函数需要调用栈帧,是有消耗的),怎么解决

  1. C语言使用宏函数(不能调试)

  2. C++使用内联函数(调用函数时展开,没有函数栈帧的开销)

    inline void Swap(int &x1,int &x2)
    {
        int tem=x1;
        x1=x2;
        x2=tem;
    }
    
    1. 以空间换时间

    2. 一般内敛适用于小函数,小于20行

特性

  1. inline是一种以空间换时间的做法,省去调用函数开销
  2. inline对于编译器来说只是一个建议,编译器会自动优化
  3. inline不建议声明定义分离,(内联函数没有地址)分离会导致链接错误,因为inline被展开后就没有函数地址了,链接就会找不到

C++中宏的替代

define N 10
const int N=10;
宏函数---->inling函数替代

宏的优缺点

优点

  1. 增强代码的复用性
  2. 提高性能

缺点

  1. 不方便调试
  2. 代码可读性差,可维护性差,容易误用
  3. 没有类型安全的检查

auto关键字(C++11)

int main()
{
	int a=0;
	auto b=a;//b的类型是由a的类型推导的
    cout<<typeid(a).name()<<endl;
    cout<<typeid(b).name()<<endl;
	return 0;
}
  1. auto不能做参数

  2. auto不能做数组

基于范围的for循环

int main()
{
	int arr[]={1,2,3,4,5};
	//数据×2,打印
    //C语言
    for(int i=0;i<5;++i);
    {
        arr[i]*=2;
        cout<<arr[i]<<" ";
    }
    //C++11->范围for(语法糖)
    for(auto &e:arr)
    {
        e*=2;
        cout<<e<<" ";
    }
}
int main()
{
	//C
	int *p1=NULL;
    //C++推荐
	int *p2=nullptr;
    //原因:C++中NULL就是0
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值