《每日一练合集》
2.6 vivo 2020校招 拆礼物算法
实际来看!!!当拆到礼品之后就不会再拆了,所以礼物后面的盒子就不用考虑了。
#include<iostream>
#include<string>
using namespace std;
int solution(string str)
{
int sum = 0;
for (auto ch : str) {
if (ch == '(') ++sum;
else if (ch == ')') --sum;
else break;
}
return sum;
}
int main()
{
string str("");
getline(cin, str);
int sum = solution(str);
cout << sum << endl;
return 0;
}
2.7 驱动中的__init
和__exit
一般在驱动中,模块的加载入口函数和卸载函数前面都会有如下的:
//模块装载和卸载函数入口的实现
static int __init hello_drv_init(void)
{
//一般向系统申请资源
printk("-----------%s init------------\n", __FUNCTION__);
return 0;
}
static void __exit hello_drv_exit(void)
{
//释放申请的资源
printk("-----------%s exit------------\n", __FUNCTION__);
}
//模块装载和卸载函数入口的声明
module_init(hello_drv_init); //实现函数原型一定是 返回值int 参数void __init是给编译器看的
module_exit(hello_drv_exit);
由于Linux是十分看重内存的节约的,所以对于那些只调用一次的函数,调用完成之后就应该释放内存。
在函数前加上__init
标记后,标记的函数会被放到ELF文件的特定代码段,在模块加载这些段的时候会单独分配内存,函数调用之后,模块的加载程序会释放这段空间;
__exit
用于修饰清除函数,作用和__init
类似,用于模块的卸载,如果模块不允许卸载,修饰的函数就不会被加载。
2.8 Linux中的挂载
Linux中一切皆文件,所以访问硬件设备都是以访问文件的形式来的。比如在使用U盘的时候,U盘本身是有文件目录的,Linux不可以直接操作其目录文件,所以要将U盘的文件目录挂载在Linux的文件目录之下,这样Linux就可以操作数U盘的文件目录了。
所以挂载就是将设备文件的目录连接到Linux的目录下,访问挂载的目录就相当于访问设备文件本身,但是并不是任意目录都可以作为挂载点,挂载点需要注意几点:
- 挂载点是已存在的目录
- 尽量使用不会被其他进程使用的目录作为挂载点
- 挂载点原有的文件会被隐藏
Linux中通过mount
命令挂载目录,通过umount
解除挂载,具体的使用参考下面文章:
https://www.linuxidc.com/Linux/2016-08/134666.htm
2.9 代码的内存分布
C语言的五大内存分布区域:
- 堆区:由程序员手动申请释放,空间分配方式类似链表
- 栈区:存放局部变量、函数的参数,由编译器自动释放与申请
- 全局变量、静态数据区:存放全局变量以及静态变量,包括data段以及bss段
- 程序代码区:存放二进制可执行程序的代码
- 常量区:存放常量字符串,程序结束后由系统释放
在一段程序中分析如下:
2.10 数组定义与引用
如何定义一个数组的引用?如下怎么样:
int &a[10];
不行的,因为数组定义中的类型不能是引用,也就是没有引用数组这种概念。虽然没有引用数组这种数据结构,但是对数组进行引用操作是可以的,如下:
int a[3] = {1, 2, 3};
int (&p)[3] = a;
而且对于数组的定义,数组元素数必须使用大于等于1的常量表达式!!!也就是说定义一个变量作为数组元素数是不行的,但是定义一个宏定义作为元素数是可以的。如果数组的大小未定,可以使用动态申请数组的方式:
int *p = new int[n];
delete []a;
数组元素初始化的时候,如果没有提供元素的初始值,就会以普通变量的形式初始化,通俗的讲全局变量是会被自动初始化为0的,局部变量无初始化,但是局部数组如果给了一些初始值,就会将剩余的元素初始化为0.