IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 标准C++程序设计学习笔记(五)——C++中的运算符别名和函数 -> 正文阅读

[C++知识库]标准C++程序设计学习笔记(五)——C++中的运算符别名和函数

目录

运算符别名

函数

C++中支持重载

C++中支持(默认值)缺省值

C++支持哑元

C++支持内联

C与C++的隐式声明


运算符别名

  • &&? ?->? ?and

  • ||? ? ?->? ? or

  • ! ? ? ?->? ? not

  • & ? ?->? ??bitand

  • ^? ? ?->? ??xor

  • {? ? ?->? ??^%

  • }? ? ?->? ??%^

  • [? ? ?->? ?? <:

  • ]? ? ?->? ?? :>

#include <iostream> //17per.cpp
using namespace std;


int main(){
	int year; 
	cin >> year;
	if(year%4==0 and year%100!=0 or year%400==0){
		cout << "闰年" << endl;
	}
	int arr<:5:> = <%5,4,3,1,2%>;	//重命名使用 [] 和 {}
	cout << arr<:3:> << endl;	
	return 0;	
}

//个人感觉没啥人会去用这东西? 真想把用的人打死

函数

C++中支持重载

  • X-函数名 Y-参数

  • 概念:C++中,在同一个作用域下面,函数名相同,参数列表不同,即构成重载

    • 前提条件:在同一个作用域下面 平等关系 (如果作用域不同,不是重载)

      • 函数名相同 函数名(一模一样)

    • 参数列表不同:

      • 参数类型不同(对应位置)

      • 参数个数不同

      • 常属性不同 (指针和引用类型的常属性不一样)

    • 与函数返回值类型无关

      #include <iostream> //18overload.cpp
      using namespace std;
      
      int max(int a,int b){
      	cout << "int,int" << endl;
      	return a>b?a:b;
      }
      
      int max(int a,int b,int c){
      	cout << "int,int,int" << endl;
      	if(a>=b && a>=c)
      		return a;
      	if(b>=a && b>=c)
      		return b;
      	return c;
      }
      double max(double a,double b){
      	cout << "double,double" << endl;
      	return a>b?a:b;
      }
      
      
      int main(){
      	cout << max(1,2) << endl;
      	cout << max(1,2,3) << endl;
      	cout << max(3.14,3.33) << endl;
      	return 0;	
      }
      

    • 重载错误:

      • 重定义(一模一样)

      • 新定义(不能变化返回值类型)

    • C++中,在调用重载的函数时,在编译阶段根据函数调用时所传递参数的个数和类型来决定调用重载函数
      ?

      #include <stdio.h>        //19func.cpp
      
      void func(){
      	
      }
      int main(){
      	
      	return 0;	
      }
      
      /*  //19func.s
      	.file	"19func.c"
      	.text
      	.globl	func
      	.type	func, @function
      func:        //宏定义的名字
      .LFB0:        
      	.cfi_startproc
      	pushl	%ebp
      	.cfi_def_cfa_offset 8
      	.cfi_offset 5, -8
      	movl	%esp, %ebp
      	.cfi_def_cfa_register 5
      	popl	%ebp
      	.cfi_def_cfa 4, 4
      	.cfi_restore 5
      	ret
      	.cfi_endproc
      .LFE0:
      	.size	func, .-func
      	.globl	main
      	.type	main, @function
      main:
      .LFB1:
      	.cfi_startproc
      	pushl	%ebp
      	.cfi_def_cfa_offset 8
      	.cfi_offset 5, -8
      	movl	%esp, %ebp
      	.cfi_def_cfa_register 5
      	movl	$0, %eax
      	popl	%ebp
      	.cfi_def_cfa 4, 4
      	.cfi_restore 5
      	ret
      	.cfi_endproc
      .LFE1:
      	.size	main, .-main
      	.ident	"GCC: (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3"
      	.section	.note.GNU-stack,"",@progbits
      
      
      */

    • 静态绑定:在编译阶段确定调用哪一个函数

    • 动态绑定:在运行阶段确定调用哪一个函数 (多态实现的一种形式)

      • 优点:

        1. 能够提高代码的可用性,使代码更加灵活。

        2. 多态是设计模式的基础,能够降低耦合性。

      • 缺点:

        1. 需要查找虚函数表来,性能比静态函数调用低。

        2. 虚函数表本身需要存储空间。

    • C++中为什么可以支持重载?

      • g++编译器会对程序中的函数名进行换名操作,将参数列表中的类型信息汇合到函数名中,以保证函数名的唯一
        ?

        #include <iostream>        //19overload.cpp   验证换名操作
        using namespace std;
        
        struct Stu{
        	int no;
        	char name[40];
        };
        
        
        void func(){
        	cout << "func()" << endl;	
        }
        //重定义
        /*
        void func(){
        	cout << "func()" << endl;	
        }
        */
        //新旧定义歧义
        /*
        int func(){
        	return 1;	
        }
        */
        void func(int a){
        	cout << "func(int)" << endl;	
        }
        void func(double b){
        	cout << "func(double)" << endl;
        }
        void func(char a){
        	cout << "func(char)" << endl;	
        }
        void func(char a,char b){
        	cout << "func(char,char)" << endl;	
        }
        void func(double a,double b){
        	cout << "func(double,double)" << endl;	
        }
        
        void func(int a,int b){
        	cout << "func(int,int)" << endl;	
        }
        /*
        void func(const int a){
        	cout << "func(const int)" << endl;	
        }
        */
        
        void func(Stu& s){
        	cout << "func(Stu)" << endl;	
        }
        void func(const Stu& s){
        	cout << "func(const Stu)" << endl;	
        }
        
        void func(int *pi){
        	
        }
        void func(const int *pi){
        	
        }
        void bar(int& x){
        	
        }
        void bar(const int& x){
        	
        }
        int main(){
        	func();
        	func('a');//
        	func(108);
        	func(3.14);
        	func('a','b');
        	//func(97,'b');//歧义
        	func(65.2,77.3);
        
        	return 0;	
        }
        /*        //  19overload.s      由于.s文件过于长且繁琐 这里截取部分说明
        	.file	"19overload.cpp"
        	.local	_ZStL8__ioinit
        	.comm	_ZStL8__ioinit,1,1
        	.section	.rodata
        .LC0:
        	.string	"func()"
        	.text
        	.globl	_Z4funcv
        	.type	_Z4funcv, @function
        
        _Z4funcv:        //可以发现针对不同形参列表的func会有不同的函数名   如此就构成了重载
        .LFB966:
        
        _Z4funci:
        .LFB967:
        
        _Z4funcd:
        .LFB968:
        
        _Z4funcc:
        .LFB969:
        
        _Z4funccc:
        .LFB970:
        
        _Z4funcdd:
        .LFB971:
        
        _Z4funcii:
        .LFB972:
        
        _Z4funcR3Stu:
        .LFB973:
        
        _Z4funcRK3Stu:
        .LFB974:
        
        _Z4funcPi:
        .LFB975:
        
        _Z4funcPKi:
        .LFB976:
        
        _Z3barRi:
        .LFB977:
        
        _Z3barRKi:
        .LFB978:
        
        */

      • C++可以不换名吗?

        • 可以,extern "C" 要求g++编译器不要对函数进行C++的换名操作,只对一个函数起作用,如果要全部需要加上{}包含函数名

        • 以方便C语言中调用C++编译生成的代码
          ?

          #include <iostream>   //20extern_overload.cpp
          using namespace std;
          
          extern "C"
          void func(){//没有
          	
          }
          
          void bar(){//变了
          	
          }
          
          
          extern "C"{
          	void call(){}//没有
          	void hello(){}//没有
          }
          
          int main(){
          	
          	return 0;	
          }
          /*    20extern_overload.s
          	.file	"20extern.cpp"
          	.local	_ZStL8__ioinit
          	.comm	_ZStL8__ioinit,1,1
          	.text
          	.globl	func
          	.type	func, @function
          func:    //由于加了extern使得不能重载操作
          .LFB966:
          
          _Z3barv:
          .LFB967:
          
          call:
          .LFB968:
          
          hello:
          .LFB969:
          
          main:
          .LFB970:
          	.cfi_startproc
          	pushl	%ebp
          	.cfi_def_cfa_offset 8
          	.cfi_offset 5, -8
          	movl	%esp, %ebp
          	.cfi_def_cfa_register 5
          	movl	$0, %eax
          	popl	%ebp
          	.cfi_def_cfa 4, 4
          	.cfi_restore 5
          	ret
          	.cfi_endproc
          */

    • 重载时函数调用匹配问题:
      • 如果在匹配过程中,没有完全的匹配,会对参数进行隐式转换

        • 如果隐式转换的过程中,发现有两个或者及其以上的函数,都能够进行相同次数转换的调用,就会产生歧义

      • 有常属性的指针和引用 可以和没有常属性的指针和引用 的函数构造重载

      • 如果非const版本和const版本都有,那么在调用时根据常属性进行匹配调用

      • 没有const属性的指针和引用可以调用 const版本的函数,但是有const属性的指针和引用不能调用非const版本的函数

      • const属性可以自动提升,但const属性不能去除

      • 如果只有一个版本的函数,没有常属性的数据可以调用const版本的,有const属性的数据一定不能调用没有const版本的函数,可以自动加强const属性,但是不能贸然丢失const属性
        ?

        #include <iostream>        //21const.cpp
        using namespace std;
        /*
        void func(int *p){
        	cout << "func(int *)" << endl;	
        }
        */
        
        void func(const int *p){
        	cout << "func(const int *)" << endl;	
        }
        
        
        int main(){
        	int *p1;
        	const int *p2;
        
        	func(p1);//自动提升const 
        	func(p2);
        	return 0;	
        }
        

      • 先进行精确匹配,参数个数和类型完全一样
        ?

        #include <iostream>            //22namespace_and_overload.cpp
        using namespace std;
        
        namespace s1{
        	void func(int a){
        		cout << "int:" << a << endl;	
        	}	
        }
        
        namespace s2{
        	void func(double d){
        		cout << "double:" << d << endl;	
        	}	
        }
        int main(){
        	s1::func(1);// 1
        	s1::func(3.14);// 3
        	s2::func(1);//1
        	s2::func(3.14);//3.14
        	using namespace s1;
        	func(1);//int:1
        	func(3.14);//int:3
        	using namespace s2;
        	func(1);//int:1
        	func(3.14);//double:3.14
        	using s1::func;
        	func(1);//int:1
        	func(3.14);//int:3
        	using s2::func;
        	func(1);//int:1
        	func(3.14);//double:3.14
        
        
        	return 0;	
        }
        

C++中支持(默认值)缺省值

  • 在定义函数时,可以给函数参数以默认值(相当于赋值语句一样),那么在调用该函数时

  • 1.可以传递该位置的参数,也可以不传递(取缺失值)

  • 2.如果某个函数的一个参数有缺省值,那么该参数后面所以的参数都必须要有缺省值,缺省值"靠右原则"

  • 3.如果函数的声明和定义分开的情况下,那么缺省参数只能放在声明中!!!

  • 4.要注意和重载函数不产生歧义
    ?

    #include <iostream>        //23default.cpp
    using namespace std;
    
    //参数y有缺省值 该参数可以传 也可以不传  不传的采用的缺省值 
    long long int  pow(int x,int y=2){
    	long long int res = 1;
    	int i;
    	for(i=1;i<=y;i++){
    		res *= x;	
    	}
    	return res;
    }
    
    //	和缺省值产生了歧义
    long long int pow(int x){
    		
    }
    
    /*
    void func(int x=1,int y){//如果允许 func(2)
    		
    }
    */
    //声明
    void func(int x,int y=1);
    
    void bar(int x,int y=1,int z=2,int w=3){
    	cout << x << "," << y << "," << z << "," << w << endl;	
    }
    
    int main(){
    	//cout << pow(10) << endl;//调用歧义
    	cout << pow(10,2) << endl;
    	cout << pow(10,3) << endl;
    	//bar();
    	bar(0);//0,1,2,3
    	bar(100,200);//100,200,2,3
    	bar(100,200,300);
    	return 0;	
    }
    
    //void func(int x,int y=1){//分开的情况下,缺省值只能放声明中
    void func(int x,int y){
    
    }
    
    

C++支持哑元

  • 函数的参数只有类型,没有名字的形参,称之为哑元

  • 在重载++、--运算符时会使用哑元

  • 注意重载产生重定义

    #include <iostream>    //24yayuan.cpp     对不起英语太差了
    using namespace std;
    
    void func(void){
    	
    }
    
    void func(int){//int 
    	cout << "func(int)" << endl;	
    }
    /*
    void func(int x){
    	
    }
    */
    int main(){
    	func(1);
    	func(2);
    	return 0;	
    }
    


    ?

C++支持内联

  • C++ inline声明的函数

  • 1.在调用内联函数时,用函数的二进制指令代码替换掉函数调用指令,减少函数调用的时间的开销,把这种策略称为内联

  • 2.inline关键字,只是建议编辑器将指定的函数编译成内联,但仅仅是建议而已

  • 3.频繁调用的简单函数适合内联,而稀少调用的复杂函数不适合内联

  • 4.调用函数无法内联

C与C++的隐式声明

  • C语言函数的隐式声明,C++没有隐式声明,C++中调用的函数必须先声明

  • C++中如果声明函数的参数为空(啥也没写),就代表了C语言中void的作用

    • C++中不能在调用无参函数时传递实参
      ?

      #include <iostream>        //25function.cpp
      using namespace std;
      
      void func();
      int bar(){
      	
      }
      int main(){
      	//func(1,2,3);
      	bar();	
      	return 0;	
      }
      
      void func(){
      	
      }
      

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章           查看所有文章
加:2021-09-23 11:16:21  更:2021-09-23 11:18:54 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 22:55:29-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码