考点-函数

函数指针

内联函数

引用

函数重载

分文件编写

先声明,再实现(定义)

假设有如下三个文件:net.cpp、file.cpp、main.cpp,main和net中都要调用file的一些函数,C/C++是分文件编译,所以就需要再main和net中都写出这些函数的声明,太繁琐。解决办法是:写好file的头文件,里面写完所有file.cpp中的函数的声明,只需要在main和net中引入file.h头文件即可。编译链接时,会自动根据这些声明找到这些函数,最终就可以执行了。

防止头文件重复包含

重复包含就造成了函数的重复定义。

解决办法宏定义

#ifdef _SUM

#define _SUM

int sum(int a,int b);
int num = 10;
#endif
//==================================
//或者
#pragma once
//或者
_pragma("once")

//效率更高

/*
第一种方法可以指定一段代码,也可以指定一个文件,可移植性好C/C++都支持,效率低;第二种办法虽然效率高,但是只能指定一个文件
*/

指针变量作为函数的参数

#include<iostream>

void change1(int a){
    a = 100;
}

void change2(int *a){
    *a = 1000;
}


int main()
{
    int num = 10;
    change1(num);
    change2(&num);
}
  1. 程序运行 main函数入栈
  2. main中num = 10,调用change1函数,保护现场
  3. change1入栈,1中a = 10,之后改为100,结束1出栈
  4. main中调用change2函数,保护现场,传入num的地址为参数
  5. change2入栈,2中指针a指向num,*a赋值为1000,num即修改为1000,结束2出栈恢复现场

结构体内函数

之后补充……

return

return的值是放到一个安全的地方,仅限这个值,如果返回指针变量,函数结束后释放资源,这个指着变量的值保存了,但这个指针所指向的内容不保证。

  1. 如果所指向内容在堆区,会存在
  2. 如果所指向内容是在其主调函数中创建,会存在
  3. 如果所指向内容是在被调函数中创建,不会存在

递归

如果没有递归出口或者次数太多,会引起Stack Overflow

函数指针

函数地址就是存储其机器语言代码的内存的开始地址。

函数名就是函数的地址。

returnType (* pf)(typeOfAgr1, typeOfAgr2, ...) = func;
//调用如下
(*pf)(a, b);



//不加括号类似函数声明
int* pf(int, int);
//这是一种返回值为 int* 类型的函数声明

函数指针常用于函数的回调。

宏函数

#define GETSUM(a,b) ((a)+(b))

注意宏函数是在预编译阶段运行的,替换完成后,如果宏函数中的每个表达式不加括号,很可能出现问题。(运算优先级引起的)

宏函数以空间换时间,不会调用函数发生保护现场、入栈等系列操作,更快。

内联函数

引用

//引用就是别名
int num = 10;
int& rnum = num;
//rnum == num (true)

int& rnum = num;
rnum = 20;

//int * const rnum = &num;
//*rnum = 20;
  • 引用必须合法的命名空间
  • 引用必须初始化
  • 一旦初始化不能改变
  • 引用的本质是指针常量
//常量引用
const int& b = 10;
//可以用来防止修改

引用做函数参数,可以节省开辟的内存空间,从而节省时间。

不要返回函数体内创建的变量的引用,因为内存会被销毁。

引用做返回值,函数调用可以做左值。

内联函数

inline int func();
inline int func(){
    
}

/*

机制可以理解为直接把代码放到函数的位置执行
不是所有的加inline都可以做内联函数,只有可以做内联函数的会做内联编译

不能做inline的情况
1.有循环
2.太多条件判断
3.函数体太大
4.对函数进行了取地址
*/

默认参数

  • 默认参数在某个位置开始,一直到最后都是默认参数。(只能在最后且连续)
  • 默认参数放到函数原型中(声明的地方)。声明写,函数定义不写,没有错误;声明不写,函数定义写了,报错。

函数重载

函数名相同,参数不同。(顺序不同也行,返回类型不能做区别,const修饰变量不能做区别,默认参数不行)

函数重载的原理:name decoration(名称修饰)或 name mangling(名称矫正)

extern “C”

按照C的方式编译相应代码

extern "C" void fun(){
    
}

字符串函数

strlen();//不计算'\0'

//dest就是目标
char* strcpy(char* dest, const char* src);//复制src到dest中

strncpy( , , n);//复制n个

strcat();
strncat(,,n);

strcmp();//字符串比较


stricmp();//忽略大小写比较
strnicmp();//比较前几个字符,忽略大小写

strchr();//查找第一次出现位置地址

char * strstr(const char* str, const char* substr);
//字符串中查找sub字符串


char* strtok(char* str, const char* delim);
//字符串切割函数

strupr();
strlwr();

atoi();//字符串转数字

strtod(const char* str, const char** endptr);

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

肥羊也

感谢给肥羊投喂!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值