c语言printf清内存,【C语言】2.变量内存以及printf & scanf的坑

概述

今天主要是常量变量,printf,scanf等内容。

1.变量内存分析

内存以“字节为单位”。

内存由大到小寻址。

int a, int b 的顺序来声明变量,则内存中a的地址在下面(即先申请,因为内存由大到小寻址),b的地址在a上面;int b, int a 则是b先申请在内存的下面。

类似Excel表格的变量在内存中的存储形式。每一个格代表一个字节(内存的单位)。 以int类型为例,四格为一个int类型的变量,从下往上排列(内存由大到小寻址),内存地址为16进制的数,比如从大到小为0xff218,0xff217,0xff216,0xff215为一个整形变量所占内存,0xff215为该变量的地址(指针)。下一个变量则挨着0xff215继续向上四个,以此类推。

类型 16位编译器 32位编译器 64位编译器

char 1 1 1

int 2 4 4

float 4 4 4

double 8 8 8

short 2 2 2

long 4 4 8

long long 8 8 8

void* 2 4 8

关键字 所占字节数 表示范围

int 4 -2(31) ~ 2(31)-1

signed short int 2 -2(15) ~ 2(15)-1

signed long int 4 -2(31) ~ 2(31)-1

unsigned int 4 0 ~ 2(32)-1

unsigned short int 2 0 ~ 2(16)-1

unsigned long int 4 0 ~ 2(32)-1

float 4 绝对值E-37 ~ E+38

double 8 绝对值E-307 ~ E+308

2. printf(位宽和控制实型位数的问题)

格式化字符串时,%ms或者%md,%mi这种格式,m为一个整数,表示想要一共保留多少位。如%5d则表示留5列(位)。(位宽)

如果当前的操作数超出想要保留的位数,则突破m的限制,保留本身的位数。如果当前的操作数小于想要保留的位数,则默认在左侧补充空格。

如果为%-md这种形式,则表示在当前操作数小于m的适合变成在右侧补充空格。

在输出实型的时候,对于单精度数,使用%f格式符输出时,仅前7位是有效数字,小数6位。对于双精度数,使用%lf格式符输出时,前15位是有效数字,小数6位。

假如输出float,%.2f这种形式,如果是3.148,则结果为3.15,自动四舍五入。

如果当前数是3.14,输出的时候要求%5.5f,既要求满足一共5位,又要求小数点后也要有5位,无法同时满足,则输出结果是3.14000,优先满足小数位。

在%后面加上.m表示想要保留多少位小数,这个不同于上面提到的,如果没有小数点那么当操作数位数大于m的时候会突破限制保留当前的位数,但是以%.m这种形式保留小数则是直接保存想要多少位的数。若当前操作数小于m,则在后面补空格。自我理解:整数允许突破限制是想要保证精度和正确,小数则可以忽略不想要的部分,因为可能对精度的影响小。

%08d表示保留8列,不足用0来补充。

printf("%.2f", 3.1415926535f); 输出结果: 3.14

通过%m方式, 指定输出数值宽度(左端补空格)

printf("%9f", 3.1415926535f);

输出结果: $3.141593 注意$代表空格

这个例子,想要输出9列浮点数,但是浮点数最大七位,既3141593,算上.只有8位,要满足9列则在左面加上空格。

指定保留多少位小数时, 可以通过*号占位, 以后赋值具体保留的小数位

printf("%.*f", 4,3.1415926535f); 输出结果: 3.1416

要求输出3.1415926535f所有小数

尝试通过指定保留位数

printf("%.10f", 3.1415926535f);

printf("%.10f", 314159.26535f);

输出结果: 3.1415927410

输出结果: 314159.2500000000

float有效数字是7位, 多余位数则会显示垃圾数据(不准确)

尝试指定宽度

printf("%12f", 3.1415926535f);

输出结果:

$$$$3.141593

尝试指定宽度和保留位数

printf("%12.10f", 3.1415926535f);

输出结果: 3.1415927410

要想完整输出必须使用double,因为double类型精度小数点后6位,有效数字是15位

double doubleValue = 3.1415926535; // 注意后面没有f

printf("%.10lf", doubleValue);

输出结果:3.1415926535

3. scanf的坑

除"空格","回车","tab"之外, 如果输入的数据和scanf接收的数据不匹配将会自动结束接收。

如果在输入时,输入了多个空格、回车、Tab都会被系统忽略的。

如果要获取的内容是多个整数,中间输入了多个空格、回车、Tab都会被系统忽略。

如果要获取的内容是多个实型,中间输入了多个空格、回车、Tab都会被系统忽略。

当整形的数和字符混合输入时,要避免“空格” 添麻烦。

为防止混合输入空格造成的错误,可以通过添加普通的分隔符解决。如","。

scanf函数当遇到回车的时候,会结束执行。

所以在scanf中,尽量不要使用 \n。如果在scanf中使用了\n, 需要原样输入"\n"。

4. scanf函数实现原理

系统会将用户输入的内容了放入输入缓冲区。

scanf方式会从输入缓冲区中逐个取出内容赋值给格式符,如果类型不一致不会修改原有数据。

如果输入缓冲区的内容不为空,scanf会一直从缓冲区中获取,而不要求再次输入。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值