C++基础 day02 布尔类型,函数重载,内联函数,哑元参数,引用,常引用
in C/C++ with 0 comment

C++基础 day02 布尔类型,函数重载,内联函数,哑元参数,引用,常引用

in C/C++ with 0 comment

复习:

语言概述

第一个C++程序

#名字空间

无名名字空间

::成员;

C++结构体、联合体、枚举

C++字符串string



new

bool类型

#例子

布尔类型变量使用

#include <iostream>
using namespace std;

int main(void)
{
    bool b = false;
    cout << sizeof(b) << endl;
    //boolalpha:流控制符以字符串形式打印bool值
    cout << boolalpha << b << endl;//false
    b = 100;
    cout << b << endl;//true
    b = 3.14;
    cout << b << endl;//true
    b = NULL;
    cout << b << endl;//false
    return 0;
}

操作符别名(了解)

&& --> and
|| --> or
^ --> xor
{ --> <%
} --> %>

#例子

操作符别名举例

#include <iostream>
using namespace std;

int main(void)
<%
    int a = 1;
    int b = 0;
    if(a and b)<%
        cout << "true" << endl;    
    %>
    else<%
        cout << "false" << endl;
    %>
    return 0;
%>

C++函数

1 函数重载

eg:图形库,里面包含绘图函数

   C:
   drawRect(int x,int y,int w,int h);
   drawCircle(int x,int y,double r);
   ...
   C++:
   draw(int x,int y,int w,int h);
   draw(int x,int y,double r);  
   … 

1)定义

在相同的作用域,定义同名的函数,但是它们的参数必须有所区分,这样函数构成重载关系。
注:函数重载和返回值无关

2)函数重载匹配

调用函数时,编译器根据实参到形参的匹配程度,自动选择最优重载版本。
当前编译器g++ V4.8.1匹配原则:

完全匹配>常量转换>升级转换>降级转换>省略号

3)函数重载原理

C++编译器是通过对函数进行换名,将参数表的信息整合到函数名中,解决函数重载与名字冲突的矛盾。
笔试题extern "C"的作用?
函数声明前面加入extern "C",要求C++编译器不会函数做换名,便于C程序去调用该函数。

语法:

  extern "C" void func(..){...}
  extern "C"{
          void func1(..){...}
          void func2(..){...}
          ...
  }

#举例

函数重载

#include <iostream>
using namespace std;

int foo(int a){
    cout << "foo(int)" << endl;
}
void foo(int a,int b){
    cout << "foo(int,int)" << endl;
}
double foo(void){
    cout << "foo(void)" << endl;
}
void foo(int a,float f){
    cout << "foo(int,float)" << endl;
}
int main(void)
{
    foo(10);
    foo(10,20);
    foo();
    foo(10,1.23f);
    //通过函数指针调用重载函数时,由函数指针类型
    //决定调用哪个版本
    void (*pfunc)(int,int) = foo;
    pfunc(10,1.23f);
    return 0;
}

函数重载匹配

#include <iostream>
using namespace std;
//char-->int:升级转换 
void func(int i){
    cout << "func(1)" << endl;
}
//char-->const char:常量转换
void func(const char c){
    cout << "func(2)" << endl;
}
//short->char:降级转换
void bar(char c){
    cout << "bar(1)" << endl;
}
//short->int:升级转换
void bar(int i){
    cout << "bar(2)" << endl;
}
//short-->long long int:过分升级转换
void bar(long long int){
    cout << "bar(3)" << endl;
}

//...:不定长参数,匹配任意多个任意类型的实参
//省略号匹配,最差
void hum(int i,...){
    cout << "hum(1)" << endl;
}
//double->int:降级转换
void hum(int i,int j){
    cout << "hum(2)" << endl;
}
int main(void)
{
    char c = 'A';
    func(c);
    short s = 10;
    bar(s);
    //hum(int,double)
    hum(123,1.23);
    return 0;
}

2 函数哑元参数

1)定义:只有类型而没有变量名参数称为哑元

eg:
void func(int){}

2)使用场景:

--》兼容以前旧代码

算法函数:

void math_func(int a,int b){…}
使用:

    int main(void){
        ...
        math_func(10,20);
        ...
        math_func(30,40);
        ...
    }
升级后算法函数:
    void math_func(int a,int){...}

--》操作符重载时,区分前后++/--

函数缺省参数(默认参数/默认实参)

4 内联函数 inline

C++的动态内存分配

//笔试:C中malloc/free和C++中new/delete区别

1 回顾C中动态内存分配

2 C++中动态内存分配

//int* pi = (int*)malloc(4);
int* pi = new int;
int* pi = new int(0);//分配内存同时初始化
...
//free(pi)
delete pi;
pi = NULL;

eg:
int* parr = new int[10];
parr[0] = ..
parr[0] = ..
delete[] parr;
parr = NULL;

#举例

C++动态内存分配举例

#include <iostream>
using namespace std;

int main(void)
{
    int* pi = new int;
    *pi = 100;
    cout << *pi << endl;
    delete pi;//避免内存泄露
    pi = NULL;//避免出现野指针
    
    //分配内存同时初始化
    int* p2 = new int(200);
    cout << *p2 << endl;//200
    (*p2)++;
    cout << *p2 << endl;//201
    delete p2;
    p2 = NULL;

    //分配数组
    //int* parr = new int[10];
    //分配数组同时初始化,需要C++11支持
    int* parr = new int[10]{10,9,8,7,6,5,4,3,2,1};
    for(int i=0;i<10;i++){
        //parr[i] = i+1;
        cout << parr[i] << ' ';
    }
    cout << endl;
    delete[] parr;
    parr = NULL;

    return 0;
}

C++的引用(Reference)

1 定义

注:引用的类型与绑定的变量的类型要一致
注:引用必须在定义同时初始化,初始化以后,所绑定的变量不能再修改。

eg:
int a = 100;
int& b = a;//b是引用,也就是a的别名
b = 200;
cout << a << endl;//200
int c = 300;
b = c;//将c的赋值给b等价赋值给a
cout << a << endl;//300

#举例

引用举例

#include <iostream>
using namespace std;

int main(void)
{
    int a = 10;
    int& b = a;//b引用a,就是a的别名
    cout << "&a=" << &a << ",&b=" << &b << endl;
    cout << "a=" << a << ",b=" << b << endl;
    b++;
    cout << "a=" << a << ",b=" << b << endl;
    int c = 22;
    b = c;//赋值,而不是修改引用目标
    cout << "a=" << a << ",b=" << b << endl;
    return 0;
}

2 常引用

eg:
    int a = 10;
    //int const& b = a和下面等价
    const int& b = a;//b是a的常引用
    b = 20;//error

#举例

常引用举例

#include <iostream>
using namespace std;

int main(void)
{
    int a = 100;
    const int& ra = a;//ra就是a的常引用
    //ra = 200;//error

    int& r = a;//a是左值,ok
    //int& r2 = 100;//100是右值,error
    const int& cr = 100;//ok
    return 0;
}

3)普通引用只能引用左值,常引用既能够引用左值也能引用右值,也称为万能引用。

左值:能够放在赋值运算符"="左侧,可以修改
右值:只能放在赋值运算符"="右侧,不能修改

#举例

万能引用举例

#include <iostream>
using namespace std;

int foo(void){
    int a = 123;
    cout << "&a=" << &a << endl;
    return a;//临时变量=a
}
int main(void)
{
    //int r = 临时变量
    const int& r = foo();
    cout << r << endl;//123
    cout << "&r=" << &r << endl;//临时变量的地址
    return 0;
}

3 引用型函数参数

#举例

引用型函数参数举例

#include <iostream>
using namespace std;
void swap1(int* x,int* y){
    *x = *x ^ *y;//011 ^ 101 = 110(x)
    *y = *x ^ *y;//110 ^ 101 = 011(y)= 3
    *x = *x ^ *y;//110 ^ 011 = 101 (x) = 5
}
void swap2(int& x,int& y){
    x = x ^ y;
    y = x ^ y;
    x = x ^ y;
}
int main(void)
{
    int a = 3,b = 5;
    //swap1(&a,&b);
    swap2(a,b);
    cout << "a=" << a << ",b=" << b << endl;
    //练习:实现交换两个const char*字符串
    //要求使用引用型参数
    const char* s1 = "hello world!";
    const char* s2 = "abcdefg";
    swap3(s1,s2);
    cout << "s1=" << s1 << endl;//abcdefg
    cout << "s2=" << s2 << endl;//hello world!
    return 0;
}
Responses