C++启蒙笔记(五)---函数进阶

一、函数与指针

1.1 函数指针

  • 函数指针
    • 定义:函数名同时也是这个函数的指针(数据类型为函数,存储函数入口地址)
    • 功能:可用来调用函数或作为其他函数实参
    • 用途:
      • 封装:函数指针可以放在结构体里,不同结构体里可包含相同的函数名不冲突
      • 动态:可以动态设置内容,灵活性,根据需要调用相应函数指针
  • 示例代码
    #include <iostream>
    using namespace std;
    
    // typedef语句:
    //   创建数据类型别名如 typedef double a_b;
    // 以下语句意义:
    //   pfun为 一类函数指针 的 数据类型 别名 :
    //		接收一个整型(int)参数,不返回值(void)
    typedef void (*pfun)(int);		
    // 此处定义变量pf1,若无此句,则无法在主函数给pf2赋值
    void pf1(int x);				
    /**************************************************************/
    int main()
    {
    	// pf1和pf2都是函数指针
    	// 且函数的返回值 和 参数的类型和数量 都要相同才可以这样赋值
    	pfun pf2 = pf1;				
    	
    	// 推荐:函数指针pf2等于pf1,(*pf2)为函数名,使用函数名调用
    	(*pf2)(3);		
    	// 功能同上:函数指针pf2等于pf1,pf1函数指针和函数名相同,故pf2也可直接调用函数
    	pf2(3);						
    }	
    /**************************************************************/
    void pf1(int x)
    {
    	cout << x << endl;
    }
    

1.2 函数指针数组

  • 功能:集成多个函数指针到一个数组里,用数组指针调用各个函数
    #include <iostream>
    using namespace std;
    
    // pfun为函数的指针,此类函数特点为返回double,参数为一个int
    typedef double(*pfun)(int);			
    // 声明两个全局函数
    double f1(int x);
    double f2(int x);
    /**************************************************************/
    int main()
    {
    	// 数组parr存的元素都为pfun这种数据类型
    	// 即:parr[0] = f1, parr[1] = f2
    	pfun parr[2] = { f1,f2 };		
    	
    	// parr_1定义、初始化:定义parr_1为含有 两个pfun类型元素 的数组指针 
    	// &parr为数组的首地址,parr为首元素的地址
    
    	// 将数组的首地址&parr赋值给parr_1,parr_1指向数组parr[2]的首地址(非首元素)
    	pfun (*parr_1)[2] = &parr;	
    		
    	// 输出:"f1函数",parr[0] = f1
    	parr[0](9);		
    			
    	// 输出:"f1函数",*parr_1等于parr,依据:parr_1的定义赋值语句确定的
    	(*parr_1)[0](9);		
    		
    	// 输出:"f1函数",**parr_1等于(*parr_1)[0],依据:数组的定义确定的
    	(**parr_1)(9);				
    	
    	
    	// 输出:"f2函数",parr[1] = f2
    	parr[1](9);		
    				
    	// 输出:"f2函数",*parr_1等于parr
    	(*parr_1)[1](9);	
    			
    	// 输出:"f2函数",(*parr_1)[1]等于(*(*parr_1+ 1))
    	(*(*parr_1+ 1))(9);			
    	
    }
    /**************************************************************/
    double f1(int x)
    {
    	cout << "f1函数" << endl;
    	return 0;
    }
    
    double f2(int x)
    {
    	cout << "f2函数" << endl;
    	return 0;
    }
    

二、引用

2.1 功能

  • 定义:一种数据类型,相当于变量别名,共用变量内存块,称为指向变量的引用
  • 特点:必须在定义的同时赋值,常用于类与结构

2.2 传值、指针和引用适用范围

  • 函数不修改实参
    • 按值传递:数据对象很小的一类
    • 指针:数据对象为数组或结构,指针需要声明为常量指针
    • 引用:数据对象为类对象
  • 函数修改实参
    • 指针:小数据及数组
    • 引用:结构、类对象

2.3 引用实现

  • 变量引用
    int rat = {};
    // 注意与取地址的区别(&在等号的左边)
    int &cat = rat;						
    
  • 函数结构引用
    #include <iostream>
    #include <string>
    using namespace std;
    
    struct product
    {
    	std::string name;
    	int bottle;
    };
    
    void display(const product & dis_good);
    product & good_add(product & good_sum, const product & good_from);
    
    /**************************************************************/
    int main()
    {
    	product one = { "啤酒:",8 };
    	product two = { "白酒:",3 };
    	product three = { "威士忌:",9 };
    	product total = { "累计:" };
    
    	// 将one加到total里,返回total的引用给display
    	display(good_add( total , one ));				
    	// 连续调用(参照注释返回引用的函数)
    	good_add( good_add( total, two ) , three);		
    	display( total );
    }
    /**************************************************************/
    
    // 功能:累加瓶数到good_sum
    product & good_add(product & good_sum, const product & good_from)	
    {
    	// 累计计算瓶子的数目
    	good_sum.bottle += good_from.bottle;		
    	return good_sum;
    }
    
    // 功能:输出传入结构的名字:瓶数
    void display(const product & dis_good)								
    {
    	cout << dis_good.name << dis_good.bottle << endl;
    }
    
    • 注释
      • display函数:传入的参数均会被隐式转化成const类参数,编程者须保证同类型的const和非const转换,避免非同类型转换

      • 返回引用的函数(good_add函数)
        • 写法一:product good_add(product & good_sum, const product & good_from)
          • return good_sum;:返回的是被实参指向的形参结构good_sum的一个拷贝
          • 返回值:放在临时内存中,跟原函数无关

        • 写法二:product & good_add(product & good_sum, const product & good_from)
          • return good_sum;:返回的是被实参指向的形参结构good_sum
          • product &:表明返回的数据的数据类型为product类型的引用,即传进去的实参
      • 避免返回指向临时变量的引用
        做法:措施为返回一个作为实参传递给函数的引用,如good_sum
        后果:若不这样做,函数将成为临时变量的引用,而临时变量在函数运行后将消失

三、函数特性

3.1 默认参数

  • 定义
    // 函数声明
    double fun(int x, int y = 3, int z = 4)
  • 顺序:默认参数放在参数表右侧
  • 位置:默认参数放在函数声明处,定义处不放

3.2 函数重载

  • 定义:C++中用一个函数名定义多个函数,并以形参类型和个数区分具体调用哪个函数
  • 适用范围:函数执行相同的任务,但使用不同形式的数据时,适用函数重载
  • 声明
    // 根据1个形参,int类型区分
    double fun(int);					
    // 根据2个形参,int,double类型区分
    double fun(int, double);			
    // 根据2个形参,double,int类型区分
    double fun(double, int);			
    
  • 调用
    // 选用第一个声明
    fun(3);				
    // 选用第二个声明				
    fun(3,2.3);			
    // 选用第三个声明				
    fun(2.3,3);							
    
  • 特例
    • 返回值区分:double fun();int fun();一样
    • 引用区分:x和&x一样
    • const区分:void fun(const char * pt){}接收的实参无限制,void fun(char * pt){}只接受非const实参,若此二者出现在一个重载函数里,非const实参给后者,const实参给前者

四、内置函数

4.1 时间函数

  • 代码示例
    #include <iostream>
    #include <ctime>
    
    using namespace std;
    
    int main()
    {
        struct tm st_set;
        //秒,直接赋值:0~59
        st_set.tm_sec = 10;
        //分,直接赋值:0~59
        st_set.tm_min = 10;
        //小时,直接赋值:0~23
        st_set.tm_hour = 6;
        //日期的日,直接赋值:1~31
        st_set.tm_mday = 25;
        //月份,减一赋值: 0~11
        st_set.tm_mon = 2;
        //年份,减1900赋值
        st_set.tm_year = 120;
        //周几,直接赋值:0是周日
        st_set.tm_wday = 6;
    
        // 当前时间戳:time()
        time_t time_now;
        time(&time_now);
    
        // a、时间戳=>时间结构:localtime(),传入时间戳,返回指向结构的指针
        struct tm *st_now;
        st_now = localtime(&time_now);
    
        // a、时间结构=>时间戳:mktime(),传入指向结构的指针
        if (time_now == mktime(st_now))
            cout << "时间戳测试无误" << endl;
    
        // b、时间结构=>字符串:strftime(),传入时间结构指针
        char date_str[20] = {};
        strftime(date_str, sizeof(date_str), "%Y-%m-%d %H:%M:%S", st_now);
        cout << date_str << endl;
    }
    

上一篇:C++启蒙笔记(四)—函数
下一篇:C++启蒙笔记(六)—类(一)

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值