c语言字符输出格式化

符号属性     长度属性     基本型     所占位数     取值范围       输入符举例      输出符举例

--            --          char         8         -2^7 ~ 2^7-1        %c          %c、%d、%u

signed        --          char         8         -2^7 ~ 2^7-1        %c          %c、%d、%u

unsigned      --          char         8         0 ~ 2^8-1           %c          %c、%d、%u

[signed]      short       [int]        16        -2^15 ~ 2^15-1              %hd

unsigned      short       [int]        16        0 ~ 2^16-1             %hu 、%ho、%hx

[signed]      --           int         32        -2^31 ~ 2^31-1              %d

unsigned      --          [int]        32        0 ~ 2^32-1              %u 、%o、%x

[signed]      long        [int]        32        -2^31 ~ 2^31-1              %ld

unsigned      long        [int]        32        0 ~ 2^32-1             %lu 、%lo、%lx

[signed]      long long   [int]        64        -2^63 ~ 2^63-1             %I64d

unsigned      long long   [int]        64        0 ~ 2^64-1          %I64u、%I64o、%I64x

--            --          float        32       +/- 3.40282e+038         %f、%e、%g

--            --          double       64       +/- 1.79769e+308 %lf 、%le、%lg   %f、%e、%g

--            long        double       96       +/- 1.79769e+308        %Lf 、%Le、%Lg

几点说明:

1. 注意! 表中的每一行,代表一种基本类型。“[]”代表可省略。

   例如:char、signed char、unsigned char是三种互不相同的类型;

   int、short、long也是三种互不相同的类型。

   可以使用C++的函数重载特性进行验证,如:

   void Func(char ch) {}

   void Func(signed char ch) {}

   void Func(unsigned char ch) {}

   是三个不同的函数。

2. char/signed char/unsigned char型数据长度为1字节;

   char为有符号型,但与signed char是不同的类型。

   注意! 并不是所有编译器都这样处理,char型数据长度不一定为1字节,char也不一定为有符号型。

3. 将char/signed char转换为int时,会对最高符号位1进行扩展,从而造成运算问题。

   所以,如果要处理的数据中存在字节值大于127的情况,使用unsigned char较为妥当。

   程序中若涉及位运算,也应该使用unsigned型变量。

4. char/signed char/unsigned char输出时,使用格式符%c(按字符方式);

   或使用%d、%u、%x/%X、%o,按整数方式输出;

   输入时,应使用%c,若使用整数方式,Dev-C++会给出警告,不建议这样使用。

5. int的长度,是16位还是32位,与编译器字长有关。

   16位编译器(如TC使用的编译器)下,int为16位;32位编译器(如VC使用的编译器cl.exe)下,int为32

位。

6. 整型数据可以使用%d(有符号10进制)、%o(无符号8进制)或%x/%X(无符号16进制)方式输入输出。

   而格式符%u,表示unsigned,即无符号10进制方式。

7. 整型前缀h表示short,l表示long。

   输入输出short/unsigned short时,不建议直接使用int的格式符%d/%u等,要加前缀h。

   这个习惯性错误,来源于TC。TC下,int的长度和默认符号属性,都与short一致,

   于是就把这两种类型当成是相同的,都用int方式进行输入输出。

8. 关于long long类型的输入输出:

   "%lld"和"%llu"是linux下gcc/g++用于long long int类型(64 bits)输入输出的格式符。

   而"%I64d"和"%I64u"则是Microsoft VC++库里用于输入输出__int64类型的格式说明。

   Dev-C++使用的编译器是Mingw32,Mingw32是x86-win32 gcc子项目之一,编译器核心还是linux下的gcc。

   进行函数参数类型检查的是在编译阶段,gcc编译器对格式字符串进行检查,显然它不认得"%I64d",

   所以将给出警告“unknown conversion type character `I' in format”。对于"%lld"和"%llu",gcc理

所当然地接受了。

   Mingw32在编译期间使用gcc的规则检查语法,在连接和运行时使用的却是Microsoft库。

   这个库里的printf和scanf函数当然不认识linux gcc下"%lld"和"%llu",但对"%I64d"和"%I64u",它则是

乐意接受,并能正常工作的。

9. 浮点型数据输入时可使用%f、%e/%E或%g/%G,scanf会根据输入数据形式,自动处理。

   输出时可使用%f(普通方式)、%e/%E(指数方式)或%g/%G(自动选择)。

10. 浮点参数压栈的规则:float(4 字节)类型扩展成double(8 字节)入栈。

    所以在输入时,需要区分float(%f)与double(%lf),而在输出时,用%f即可。

    printf函数将按照double型的规则对压入堆栈的float(已扩展成double)和double型数据进行输出。

    如果在输出时指定%lf格式符,gcc/mingw32编译器将给出一个警告。

11. Dev-C++(gcc/mingw32)可以选择float的长度,是否与double一致。

12. 前缀L表示long(double)。

    虽然long double比double长4个字节,但是表示的数值范围却是一样的。

    long double类型的长度、精度及表示范围与所使用的编译器、操作系统等有关。

 

转自:http://hi.baidu.com/dhh1216_cgcg/blog/item/3c6b3a79679ddfe12e73b3c9.html

<think>我们正在讨论C语言字符格式化输出的本质。根据提供的引用,我们可以从几个方面来理解: 1. **格式化输出的核心**:C语言通过格式化输出函数(如printf)将数据按照指定格式转换为字符序列输出。这个过程本质上是一种**类型转换**和**格式控制**的结合。 2. **转换过程**: - 根据格式字符串中的格式说明符(如`%d`, `%f`, `%s`等),将内存中的二进制数据转换为人类可读的字符序列。 - 例如,整数`65`在内存中以二进制形式存储,当使用`%c`输出时,会被转换为字符`'A'`(ASCII码65);使用`%d`输出则转换为字符串`"65"`。 3. **格式控制**: - 格式说明符可以包含各种控制信息,如宽度、精度、对齐方式等(如`%5.2f`)。 - 这些控制信息指导了转换后的字符序列如何被格式化(例如,总宽度、小数位数等)。 4. **字符串处理**: - 对于字符输出(`%s`),格式化输出函数会从给定的内存地址开始,逐字符输出直到遇到空字符`'\0'`为止。 5. **底层实现**: - 格式化输出函数需要解析格式字符串,识别普通字符和格式说明符,然后根据格式说明符从变长参数列表中获取相应类型的数据,进行转换后输出。 **本质总结**:C语言字符格式化输出的本质是**将内存中各种类型的数据按照程序员指定的格式转换为字符序列,并输出到标准输出设备**。这个过程涉及: - 数据类型的解析(根据格式说明符) - 数据到字符序列的转换(遵循特定规则,如ASCII编码) - 格式控制(宽度、精度、填充等) §§相关问题§§ 1. C语言格式化输出函数如何处理变长参数列表? 2. 如何自定义一个简单的格式化输出函数来理解其原理? 3. 格式化输出过程中,如果格式说明符与实际参数类型不匹配会导致什么问题? 4. 除了printf,C语言还有哪些常见的格式化输出函数?它们有什么不同? </think>### C语言字符格式化输出的本质 C语言字符格式化输出的本质是**将内存中的二进制数据按照指定格式转换为人类可读的字符序列**,这个过程包含三个核心环节: 1. **数据解析与类型转换** 格式化函数(如`printf()`)根据格式说明符(如`%d`, `%s`, `%f`)解析内存中的原始二进制数据。例如: - `%d` 将4字节二进制整数转换为十进制字符串(如`0x2A → "42"`) - `%c` 将ASCII码值转换为字符(如`65 → 'A'`) - `%f` 将IEEE 754浮点数据转换为小数形式(如`0x4048F5C3 → "3.14"`) 2. **格式控制与布局** 通过格式修饰符精确控制输出样式: - **宽度控制**:`%5d` 强制输出占5字符宽度(不足补空格) - **精度控制**:`%.2f` 限制浮点数小数位(`3.14159 → "3.14"`) - **对齐填充**:`%-10s` 左对齐字符串(`"AB" → "AB        "`) 这些规则在编译时生成格式解析状态机[^3]。 3. **字符序列生成** 最终调用底层`write`系统调用,将转换后的字符序列送入输出缓冲区。例如: `printf("Name: %-8s Age:%03d", "Li", 25)` 内存操作流程: ```plaintext 原始数据: "Li"(地址0x1000) + 25(0x2000) ↓ 格式解析 字符流: 'N','a','m','e',':',' ','L','i',' ',' ',' ','A','g','e',':','0','2','5' ↓ 系统调用 终端显示: "Name: Li       Age:025" ``` **关键特性**: - **弱类型依赖**:C语言不检验数据类型与格式符的匹配,依赖程序员确保正确性(错误匹配导致未定义行为)[^1] - **内存直接操作**:通过变长参数机制(`va_list`)直接访问调用栈中的数据内存[^2] - **编码转换**:非ASCII字符需按本地编码(如UTF-8)转换字节序列 > 示例:`printf("%#08X", 42)` > 1. 读取格式符`%#08X` > 2. 从栈中取出整数`42` (二进制`00101010`) > 3. 转换为十六进制字符序列`"2A"` > 4. 添加前缀`0x`并补零至8字符:`"0x00002A"` > 5. 输出到终端
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值