函数指针
内联函数
引用
函数重载
分文件编写
先声明,再实现(定义)
假设有如下三个文件: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);
}
- 程序运行 main函数入栈
- main中num = 10,调用change1函数,保护现场
- change1入栈,1中a = 10,之后改为100,结束1出栈
- main中调用change2函数,保护现场,传入num的地址为参数
- change2入栈,2中指针a指向num,*a赋值为1000,num即修改为1000,结束2出栈恢复现场
结构体内函数
之后补充……
return
return的值是放到一个安全的地方,仅限这个值,如果返回指针变量,函数结束后释放资源,这个指着变量的值保存了,但这个指针所指向的内容不保证。
- 如果所指向内容在堆区,会存在
- 如果所指向内容是在其主调函数中创建,会存在
- 如果所指向内容是在被调函数中创建,不会存在
递归
如果没有递归出口或者次数太多,会引起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 = #
//*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);