嵌入式学习笔记:第三周

C++对C的函数拓展
1、内联函数
内存空间、编译时间
①用空间换时间:inline修饰的函数(内嵌函数、内联函数);
②用时间换空间:宏定义函数
函数:通过函数名找到存放位置,给形象分配空间、传参、执行函数体里语句、函数返
回、释放空间;
宏函数:省去了形参以及函数体里需要的空间,省去了函数调用传参、返回值等;
inline:将函数加载到程序到用处, 将函数体力的语句内嵌到此函数调用处,省去了函数调
用,传参,函数返回值,提高了运行效率;
宏函数适用:频繁调用且功能简单的函数;
inline修饰:短小且不被频繁调用的函数;
C语言中:凡是用inline修饰的函数都会被内联到函数调用的地方;
C++中:用inline修饰的函数不一定被内联到调用的地方,因为编译器会自己做出判断;
条件:1内联函数中不可含有循环;
2内联函数中不可能含有静态变量;
3内联函数不可为递归函数;
4内联函数中不可含有错误处理;
(注:内联函数定义必须在该函数第一次使用之前;)
2、默认参数
①定义:C++中可以在函数声明时为参数提供一个默认值,当函数调用时没有指定这个参数的
值,编译器会自动用默认值代替
#include <stdio.h>
int mul(int a = 10); // 声明时指定默认参数
int main()
{
printf ("%d\n", mul(2));
printf ("%d\n", mul(-3));
printf ("%d\n", mul()); // 没有写参数,则默认参数
return 0;
}
int mul(int a) // 定义时不再指定
{
return a * a;
}
②规则:
1.只有参数列表后面部分的参数才可以提供默认参数值
2.一旦在一个函数调用中开始使用默认参数值,那么这个参数后的所有参数都必须使用默
认参数值
#include <stdio.h>
int add(int a, int b = 0, int c = 0)
{
return a+b+c;
}
int main()
{
printf ("%d\n", add(2));
printf ("%d\n", add(1,2));
printf ("%d\n", add(1,2,3));
return 0;
}
3、函数重载
①概念:当函数的形参个数或者顺序或者类型与已存在的函数不同时,可以用同一个函数名定义
不同的函数;
②函数重载判断标准:函数的形参个数或者顺序或者类型与已存在的函数不同;
#include <stdio.h>
#include <string.h>
int func(int x)
{
return x;
}
int func(int a, int b)
{
return a + b;
}
int func(const char* s)
{
return strlen(s);
}
int main()
{
int c = 0;
c = func(1);
printf(“c = %d\n”, c);
c = func(1, 2);
printf(“c = %d\n”, c);
c = func(“12345”);
printf(“c = %d\n”, c);
return 0;
}
③函数重载与默认参数:C++允许函数形参中有默认参数,但这回破坏重载条件;
#include <stdio.h>
int func(int a, int b, int c=0)
{
return a + b;
}
int func(int a, int b)
{
return a + b;
}
int main()
{
func(1,2); // 哪个函数会被调用
return 0;
}
④调用重载函数的准则:
将所有同名函数作为候选者;
尝试寻找可行的候选函数;
精确匹配实参;
通过默认参数能够匹配实参;
通过默认类型转换匹配实参;
匹配失败:
最终寻到的可行候选函数不唯一,出现二义性,编译失败;
无法匹配所有的候选者,函数未定义,编译失败;
⑤ 注意事项:
重载函数在本质上是相互独立的不同函数(静态链编);
重载函数的函数类型是不同的;
函数返回值不能作为函数重载的依据;
函数重载是有函数名和参数列表决定的;

一、struct结构体升级
1、定义与使用:
结构体作用:封装不同类型的数据(将不同类型的数据整合在一起,用同一种数据类型表示);
2、struct在C和C++中的区别:
C语言结构体:①只能存放变量不能存放函数;
②定义结构体变量必须加struct关键字;
C++结构体:①定义变量时不用加struct关键字;
struct student
{
int a;
int b;
};
void main()
{
student s1; //s1是struct类型的
}
②可以存放函数
③可以在结构体里加入权限修饰符;
权限修饰符:
public :公有权限;能够被外界直接访问;
private :私有权限;不能被外界变量直接访问,可以在结构体内部被
访问;
struct student
{
public:
int num;
int age;
void print1()
{
printf();
}
void setAge(int age);
private:
void print()
{
cout << age << endl;
}
};
protected :保护权限;
④可继承、可多态;
struct student{
int num;
int age;
};
struct student2{
};
void main()
{
student2 s1; //s1可调用student结构内的成员;
s1.num = 2;
s1.age = 1;
}
3、结构体内定义函数:
struct student{
int num;
int age;
void print()
{
cout << age << endl;
}
};
函数在struct内部实现和外部实现:
在struct内部实现,函数会被编译器声明修饰为内联函数;
4、struct和class的一些称呼区别:
struct class
结构体变量 类的对象
变量 对象
函数 方法
变量 属相、成员变量
5、class与struct的区别:默认权限不同:class的默认属性是private,struct的默认属性是public;
6、面向对象的代码结构:把类的定义放在一个头文件里,然后把成员函数的实现放在.cpp文件;

二、string类
在C语言中字符串的操作极易引发内存错误;
0、string的定义:string是个可变长度的字符串:
1、定义变量:
string s1 = “hello world”;
string s2(“hello world”);
string *ps = new string(“hello world”);
string s3 = “”; //空字符串
2、string的字符访问
s1的第一个字符:s1[1] == s1.at(0);
字符访问:[] 和 at() 函数:越界,[] 不会产生异常;at() 会产生异常并报错;
3、string的特性
①长度、大小(占用的内存空间)------->(不包含 ‘\0’) strlen sizeof
s1.length();
s1.size();
②存放的最大的字符数max_size()返回值代表的是内存中可以存放的字符数;
s1.max_size();
s1.capacity(); //返回当前容量(即string中不必增加内存即可存放的元素个数)
③空字符串的判断
s1.empty() == true //s1是空字符串
s1.empty() == false //s1不是空字符串
④赋值
s2 = s1;
s3 = “nice”;
s5.assign(s1) 等价于 s5 = s1;
s5.assign(s1,2,5) 等价于 把s1中第二个字符到第五个字符复制到s5中;
⑤连接
s2 = s1 + s3;
s4 = s3 + “girl”;
s5.append(s1); //把s1的内容复制粘贴到s5尾部;
s5.append(“abc”); //把abc复制粘贴到s5的尾部;
⑥比较
if(s1 == s2)cout << " == "<<endl;
if(s1 < s2)cout << " < "<<endl;
if(s1 > s2)cout << " > "<<endl;
⑦查找
int pos = s1.find(“hello”); //返回s1中第一次出现“hello”的位置
⑧迭代器————指针的泛化
作用:遍历的容器(string、vector)
string s5 = “hello world”;
//遍历
①for(int i = 0; i < s5.size(); i++)
{
cout << s5[i] << endl;
}
②for(char ch : s5)
{
cout <<ch << endl;
}
③string::iterator it; //限定迭代器的类型,不同类型的迭代器累加结果不一样;
fot(it = s5.begin(); it != s5.end(); it++)
{
cout << *it << endl;
}
//begin()是指向第一个数据
//在字符串中end()是’\0‘;
//其他类型中end()是最后一个有效数据的后一个;
④fot(auto it = s5.begin(); it != s5.end(); it++) //使用auto对it的类型进行推测;
{
cout << *it << endl; //再循环中可以对字符串进行修改
}
⑤删除字符串中某个字符:删除s5(“hello world”)中的 l
fot(auto it = s5.begin(); it != s5.end(); it++)
{
if(*it == ‘l’)
{
s5.erase(it);
it–;
}
}

三、vector
定义变量:
vector v1 = {1,2,3,4,5};
vector v2 = {“hello1”,“hello2”};
for(int i = 0; i < v1.size(); i++)
{
cout << v1[i] << endl;
}
迭代器:
vector::iterator it;
for(it = v1.begin(); it != v1.end(); it++)
{
cout << *it <<endl;
}
尾部添加:
v1.push_back(6); (v1的元素:1,2,3,4,5,6)
v1.push_back(7); (v1的元素:1,2,3,4,5,6,7)
删除:
v1.erase(v1.begin()+1); (删除从开头起的第二个元素;)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值