1、内联函数
- 内联函数引出---宏缺陷
- 宏缺陷:
- 必须要加括号保证运算完整
- 即使加括号,有些运算依然与预期结果不符
- 普通函数不会出现缺陷
- 宏缺陷:
- C 提供 内联函数代替宏函数
- 关键字 inline
- 在函数声明和实现中同时加入关键字 inline 才称为内联
- 在成员函数前 都隐式加了关键字inline
- 有些特殊情况下 ,写了关键字inline也不会按照内联方式处理
- 出现循环
- 出现判断
- 函数体过于庞大
- 对函数进行取地址
- 总结: 内联函数只是给编译器一个建议,但是编译器不一定接受这个建议,好的编译器会自己给短小的函数前加上关键字inline
代码
代码语言:javascript复制#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
//宏缺陷1 : 必须要加括号保证运算完整
#define MYADD(x,y) ((x) (y))
void test01()
{
int a = 10;
int b = 20;
int ret = MYADD(a, b) * 20;
cout << ret << endl;
}
//宏缺陷2: 即使加了括号,有些运算依然与预期不符
#define MYCOMPARE(a,b) (((a) < (b)) ? (a) : (b))
//普通函数 不会出现与预期结果不符的问题
void myCompare(int a, int b)
{
int ret = a < b ? a : b;
cout << "ret = " << ret << endl;
}
void test02()
{
int a = 10;
int b = 20;
myCompare( a, b);
//int ret = MYCOMPARE( a, b); //预期是 11 结果变为12 ((( a) < (b)) ? ( a) : (b))
//cout << "ret = " << ret << endl;
}
2、函数的默认参数和占位参数
函数的默认参数和占位参数
- 默认参数
- 可以给函数的形参添加默认值
- 语法 形参 类型 变量 = 默认值
- int func(int a, int b = 10 , int c = 10)
- 注意事项 ,如果有一个位置有了默认参数,那么从这个位置起,从左到右都必须有默认值
- 函数的声明和实现 只能有一个 提供默认参数,不可以同时加默认参数
- 占位参数
- 只写一个类型进行占位,调用时候必须要传入占位值
- void func2(int a , int = 1)
- 占位参数也可以有默认值
代码
代码语言:javascript复制#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
//默认参数 语法 形参 类型 变量 = 默认值
//优先采用传入的值
int func(int a = 10, int b = 10)
{
return a b;
}
void test01()
{
cout << func() << endl;
}
4、函数的重载
- 满足条件
- 同一个作用域下
- 函数名称相同
- 函数参数个数、类型、顺序不同
- 函数的返回值 不可以作为重载条件
- 注意事项
- 加const和不加const的引用可以作为重载条件
- 函数重载碰到默认参数 注意避免二义性出现
代码
代码语言:javascript复制#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
//函数重载条件
//1、在同一个作用域
//2、函数名称相同
//3、参数个数、类型、顺序不同
//class Person
//{
//public:
// void func() 成员函数 而不是全局函数
// {
// }
//};
void func()
{
cout << "func()调用" << endl;
}
void func(int a)
{
cout << "func(int a)调用" << endl;
}
void func(double a)
{
cout << "func(double a)调用" << endl;
}
void func(int a, double b)
{
cout << "func(int a ,double b)调用" << endl;
}
void func(double a, int b)
{
cout << "func(double a, int b)调用" << endl;
}
//返回值可不可以作为函数重载的条件 答案:不可以
//int func(int a, double b)
//{
// cout << "func(int a ,double b)调用" << endl;
//}
void test01()
{
func(1, 3.14);
}
//函数重载中 引用两个版本
//void myFunc(int a)
//{
// cout << "myfunc(int a )调用" << endl;
//}
void myFunc(int& a) // int & a = 10;
{
cout << "myfunc(int &a )调用" << endl;
}
void myFunc(const int& a) // const int &a = 10;
{
cout << "myfunc( const int &a )调用" << endl;
}
void test02()
{
int a = 10;
//myFunc(a);//需要避免二义性出现
}
//函数重载碰到默认参数 注意避免二义性出现
void func2(int a, int b = 10)
{
}
void func2(int a)
{
}
void test03()
{
//func2(10); //出现二义性
}
5、extern C 浅析
- 用途:在C 中调用C语言文件
- C 中有函数重载,会对函数名称做修饰,导致调用C语言的函数链接失败
- 利用extern C可以解决问题
- 方法1:
- 在C 代码中加入
- 告诉编译器 show函数用C语言方式 做链接
- //extern "C" void show();
- 方法2:
- 在C语言的头文件中加入6行代码
- #ifdef __cplusplus // 两个下划线 __ c plus plus
- extern "C" {
- #endif
- #ifdef __cplusplus // 两个下划线 __ c plus plus
- }
- #endif
- 方法1:
代码
代码语言:javascript复制#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
#include "test.h"
//extern "C" void show();
void test01()
{
show();
}
int main()
{
test01();
system("pause");
return EXIT_SUCCESS;
}
6、封装
- C语言的封装
- 缺陷 将属性和行为分离
- C 语言的封装
- 将属性和行为作为一个整体,来表现生活中的事物
- 将属性和行为 加以权限控制
- 访问权限
- 公共权限 public 类内 类外 都可以访问
- 私有权限 private 类内可以访问 类外不可以访问
- 保护权限 protected类内可以访问 类外不可以访问
- class 默认权限 私有权限 而 struct默认权限是 公共权限
代码
代码语言:javascript复制#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
struct Person
{
//公共权限
public:
char name[64];
int age;
void PersonEat()
{
printf("%s在吃人饭n", name);
}
};
struct Dog
{
//公共权限
public:
char name[64];
int age;
void DogEat()
{
printf("%s在吃狗粮n", name);
}
};
//C 封装 理念: 将属性和行为作为一个整体,来表现生活中的事物
//第二次理念: 将属性和行为 加以权限控制
void test01()
{
struct Person p;
strcpy(p.name, "老王");
p.PersonEat();
//p.DogEat();
}
//struct和class 区别?
//class 默认权限 私有权限 而 struct默认权限是 公共权限
//访问权限
// public 公共权限 成员 类内 类外 都可以访问
// private 私有权限 成员 类内 可以访问 类外 不可以访问 儿子不可以访问父亲的private权限内容
// protected 保护权限 成员 类内 可以访问 类外 不可以访问 儿子可以访问父亲的protected权限内容
class Person2
{
public:
string m_Name; //公共权限
protected:
string m_Car; //保护权限
private:
int m_pwd; //私有权限
public:
void func()
{
m_Name = "张三";
m_Car = "拖拉机";
m_pwd = 123456;
}
};
void test02()
{
Person2 p;
p.m_Name = "李四"; //公共权限 类外可以访问
// p.m_Car = "劳斯莱斯"; //保护权限 类外访问不到
// p.m_pwd = 123; //私有权限 类外不可以访问
}