【C语言拓展】缓冲区、结构体大小计算、命令行参数

举报
人才程序员 发表于 2023/11/30 17:54:13 2023/11/30
【摘要】 @TOC 前言本节课主要讲的是缓冲区和结构体大小的计算之谜(二)提示:以下是本篇文章正文内容,下面案例可供参考 一、缓冲区 缓存区介绍1、缓冲区有很多:输入缓冲区,输出缓冲区,文件缓冲区,键盘缓冲区,输出双缓冲等等。 有时候还叫 buf,爸福。都是一个东西。2、缓冲区本质就是一段连续的空间,比如 char a[40];,a 就是一段连续的 40 字节的空间。 3、这个名字是根据它的功能来的,...

@TOC


前言

本节课主要讲的是缓冲区和结构体大小的计算之谜(二)


提示:以下是本篇文章正文内容,下面案例可供参考

一、缓冲区

缓存区介绍

1、缓冲区有很多:输入缓冲区,输出缓冲区,文件缓冲区,键盘缓冲区,输出双缓冲等等。 有时候还叫 buf,爸福。都是一个东西。
2、缓冲区本质就是一段连续的空间,比如 char a[40];,a 就是一段连续的 40 字节的空间。 3、这个名字是根据它的功能来的,用来处理输入数据的,就叫输入缓冲区,用来处理输出 数据的就叫输出缓冲区,宏观上取个名字,方便程序猿分析使用。
4、缓冲具体是什么样的意义? 本身就是一种有效处理问题的算法,比如输入缓冲区的处理逻辑
1、键盘输入的各种字符,都会统一的一个的存储在输入缓冲区中
2、输入完毕,scanf 等输入函数在缓冲区中拿数据,然后存入变量里 意义: 假设没有中间的缓冲区,咱们向一个 int 变量 a 中输入数据:scanf("%d", &a); 输入:123 这个数,依次摁的,然后如何存储这单个的数字? 1 先存入 a,a==1 然后存 2,此时 a 中应该是 12,所以存 2 时是加 11,a==12 然后存 3,此时 a 中应该是 123,所以存 3 时是加 111,a==123 这时发现输入错误,想输入 145,不是 123,那就得删除,还得减,惨不忍睹。 缓冲区来了,输入缓冲区是将所有的输入做字符串处理 输入 123,那就是输入的字符串 123,增删直接就是字符数组的增删了,回车表示输入 结束,然后 scanf 根据格式说明符,将数据 123 转成整数,存一下就行了。 这种逻辑可以简单理解为:整合再分发,还有很多类似的逻辑应用,拓展理解应用

缓冲区的作用

缓冲区的主要作用:平衡输入端与计算端速度不一致

缓存区的大小

输入缓冲区大小是:4096字节
测试代码:

while(1)
{
	char c = getchar();
	//你会发现,输入到一定时候就输入不动了,这个大小大概是4096字节
	//以后就不能再输入东西了
	//所以需要清空缓冲区
}

缓冲区使用的一些注意点

键盘键入后,都是以字符形式存储在存在缓冲区,所以输入缓冲区里都是字符。在输入字符 时,尤其注意此事,如下:

char a,c,e; 
a = getchar();
c = getchar();
e = getchar();
//输入
//q<\n>a<\n>c<\n>
//则a == q
//c == \n
//e == a

1、即输入缓冲内字符的残留会影响字符的输入
其他常见情形:

清空缓冲区

1、通过 getchar 函数将缓冲区搬空,无脑搬。
while ((c=getchar()) != ‘\n’ && c != EOF); //getchar读取途中出错
即使缓冲区满了,最后也是\n,没读到 EOF,暂且写上。
有 bug,该写法遇到\n 就停止,如果缓冲区残留 123\n\n456,则清完第一个\n 就结束, 残留\n456,该情况比较极端,一般正常输入完摁 1 个\n

2、清楚知道缓冲区残留 1 个\n,针对上面的常见使用情景 scanf(" %c", &c); // %c 前加个空格 或者getchar(); //先拿出来 scanf("%c", &c);

3、跳过若干个字符 scanf("%*[^\n]%*c"); 清除所有字符,遇到\n 停下,然后%*c 清除\n

4、rewind(stdin); 清空stdin输入缓冲区

二、结构体大小之谜

字节对齐

字节对齐,从形式上简单理解,比如:
char c ;
4 字节对齐,那么 c 就存储在 1 个 4 字节的单元中,占据首字节,其余 3 字节空闲。 2 字节对齐,那么 c 就存储在 1 个 2 字节的单元中,占据首字节,其余 1 字节空闲。 假设此时又有 int a;需要存储,那么 a 存储在 c 后第 4 字节处,不会占据 c 的 4 字节。 字节对齐数都是 2 的 n 次方。1,2,4,8,16 字节对齐

结构体大小计算

结构体大小计算方法、大概: 1、整体对齐:以最大的类型的字节数为对齐字节数,成员按顺序填充
2、局部对齐:填充时,与前面已分配好的的成员,最大字节对齐 3、结尾补齐:补齐最大字节数,最终为最大字节的整数呗

比如:

struct Node 
{ 
	char c;
	int h;
	double s;
	void *p;
	char str[10];
}

1、以 8 字节为模板,依次填充
在这里插入图片描述

强制设置字节对齐数:#pragma pack(1)
1 就是 1 字节对齐,那么所有成员就是 1 个挨着 1 个
不建议自己修改

什么都不写,系统默认的对齐字节,这根据成员最大的字节数决定,目的就是防止跨字 节单元存储#pragma pack( )

一般的结构体字节对齐都是8字节对齐的。
所以我们计算时就使用8字节对齐去计算

三、命令行参数

使用场景

命令行参数 命令行参数用来传递文件路径给软件,比如双击 stu.txt,系统就会自动用文本软件打开该文档, 本质就是系统通过文件后缀得知用什么软件打开,然后将文件的绝对路径传递给软件,软件内通 过 fopen 打开了 stu.txt,这就是用到了命令行参数。 另外拖动文件到软件,或者选择打开方式,或者通过控制台指令,虽然操作不一样,但是本质一 样。演示通过命令行传递参数:cmd->exe 的绝对路径(一拖一拉)->空格->文件的绝对路径

命令行参数形式

int main(int argc, char* argv[])
{ 
	return 0;
}

参数 1 是命令行参数的个数
参数 2 是字符串数组,装命令行参数的,本质就是字符串,路径,也可写成 char**argv

参数传递

1、通过命令行传递,比如:data.exe da1.txt da2.txt da3.txt argc 为 4
argv[0]为 data.exe argv[1]为 da1.txt argv[2]为 da2.txt argv[3]为 da3.txt

2、调试参数传递:项目属性->调试->命令行参数 此时不用写 exe 文件了,默认就有,直接写文件 da1.txt da2.txt da3.txt,空格隔开。 用法同上,一模一样。

总结

本节课讲的是运算符,结构体大小计算(字节对齐),命令行参数的介绍

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。