C语言显示八进制数和十六进制数

C既允许您使用3种数制书写数字,也允许以这3种数制显示数字。要用八进制而不是十进制显示整数,请用%0代替%d。要显示十六进制整数,请使用%x。如果想显示C语言前缀,可以使用说明符%#o、%#x和%#X分别生成0、0x和0x前缀。程序清单3.3是一个简短的例子(回忆一下,您需要在一些为IDE而写的代码中插入一个getchar():语句,以便程序的执行窗口不会立即关闭)。

程序清单3.3 bases.c程序


/*bases.c --以十进制、八进制和十六进制形式输出100*/

#include<stdio.h>

int main (void)

{

int x = 100;

printf("dec = %d; octal = %o; hex = %x\n", x, x, x);

printf("dec = %d; octal= %#o; hex = %#x\n", x, x, x);

return 0;

}

编译并运行上面的程序,将产生下列输出:

dec = 100; octal = 144; hex = 64

dec = 100; octal= 0144; hex = 0x64

其他整数类型

初学语言时,int类型会满足您对整数的大多数需求。但为了给出完整的介绍,现在我们将对讨论其他的类型。您也可以跳过本节,“直接阅读使用字符:char类型”小节,在以后需要的时候再阅读。

short int类型(或者简写为short类型)可能占用比int类型更少的存储空间,用于仅需小数值的场合以节省空间。同int类型一样,short类型是一种有符号类型。

long int 类型(或者简写为short类型)可能占用比int类型更多的存储空间,用于使用大数值的场合。同int类型一样,long类型是一种有符号类型。

long long int类型(或者简写为long long类型(都是在C99标准中引入的),可能占用比long类型更多的存储空间,用于使用更大数值范围为0到65535,而带符号int的取值范围为-32768。由于指示数值正负的位也用于二进制位,所以无符号数可以表示更大的数值。

在C90标准中,还允许unsigned long int(简写为unsigned long)和unsigned short int(简写为unsigned short)类型。C99又增加了 unsigned long long int(简写为unsigned long long)类型。

关键字 signed 可以和任何有符号类型一起使用,它使数据的类型更加明确。例如:short、short int、signed short以及 signed short int 代表了同一种类型。

一、声明其他整数类型

其他整数类型的声明方式同int类型相同,下面是一些例子。一些早期的C语言编译器不识别最后3条语句,最后一条语句由C99标准最新引入。

long int estine;

long johns;

short int erns;

short ribs;

unsigned int s_count;

unsigned players;

unsigned long headcount;

unsigned short yesvotes;

long long ago;

二、使用多种整数类型的原因

为什么说long和short类型“可能”占用比int类型更多或者更少的存储空间呢?因为C仅保证short类型不会比int类型长,并且long类型不会比int类型短。

三、long常量和long long常量

通常,在程序代码中使用2345这样的字母时,它以int类型存储。

四、打印short、long、long long和unsigned类型数

要打印unsigned int数字,可以使用%u符号。打印long数值,可以使用%ld格式说明符。

程序清单3.4 print2.c程序

/*print2.c--printf()的更多属性*/

#include<stdio.h>

int main(void)

{

unsigned int un=3000000000; /*int 为32位*/

short end = 200; /*和short为16位的系统*/

long big = 65537; long long verybig = 12345678908642;

printf("un = %u and not %d\n", un, un );

printf("end = %hd and %d\n", end, end);

printf("big = %ld and not %hd\n", big, big);

printf("verybig = % lld and not %ld\n", verybig, verybig);

return 0;

}

运行结果:

un = 3000000000 and not -1294967296

end = 200 and 200

big = 65537 and not 1

verybig = 12345678908642 and not 12345678908642

这个例子表明如果使用了不正确的说明符,会会造成意想不到的后果。

使用字符:char类型

char类型用于存储字母和标点符号之类的字符。但是在技术实现上char却是整数类型,这是因为char类型实际存储的是整数而不是字符。

程序清单3.5 charcode.c 程序

#include<stdio.h>

int main (void)

{

char ch;

printf("Please enter a character.\n");

scanf("%c",&ch);/*home instl*/

printf ("The code for %c is %d.\n",ch,ch);

return 0;

}

运行程序,在键入字母后不要忘记Enter或Return键。

五、有符号还是无符号

一些C实现把char当作有符号类型。这意味着char类型的值的典型范围-128到127。另一些C实现把char当作无符号类型,其取值范围为0到255。编译器手册会指明char的类型,或者您可以通过limits.h头文件检查这一信息,下面的章节对该头文件做详细介绍。

程序清单3.6 altnames.c程序

/*altnames.c--可移值的整数类型名*/

#include<stdio.h>

#include<inttypes.h> //支持可移植类型

int main(void)

{

int16_t me16; //me16是一个16位有符号变量

me16 = 4593;

printf("First, assume lnt16_t is short: ");

printf("me16 = %hd\n", me16);

printf("Next, let's not make any assumptions.\n");

printf("Instead, use a \"macro\" from inttypes.h: ");

printf("me16= %" PRId16 "\n", me16);

return 0;

}

在最后的printf()语句中,参数PRId16被它在inttypes.h里的定义“hd”所替代,因而这行语句等价于:

printf("me16 = %" "hd" "\n", me16):

C语言将三个连续的字符串合并为一个引号起来的串,因而这行语句又等价于:

printf("me16 = %hd\n", me16);

下面是输出结果,注意示例中还使用了\"转义序列来显示双引号:

ssume lnt16_t is short: me16 = 4593

Next, let's not make any assumptions.

Instead, use a "macro" from inttypes.h: me16= 4593

一、声明浮点变量

浮点变量的声明以及初始化方法同整型变量相同,下面是一些例子

float noah. jonah:

double trouble:

float planck = 6.63e-34;

long double gnp;

二、浮点常量

书写浮点常量有很多种选择。一个浮点常量最基本的形式是:包含小数点的一个带符号的数字序列,接着字母e或E,然后代表10的指数的一个有符号值。下面是两个有效的浮点常量:

-1.56E+12

2.87e-3

可以省略正号。可以没有小数点(2E5)或指数部分(19.28),但是不能同时没有二者。可以省略纯小数部分(3.E16)或整数部分(.45E-6),但是二者不能同时省略(那样做会什么也不会剩下)。下面是更多的有效浮点常量:

3.14159

.2

4e16

.8E-5

100.

在浮点常量中不要使用空格。

错误 1.56 E+12

默认情况下,编译器将浮点常量当作double类型。例如,假设some是一个float变量,您有下面的语句:

some = 4.0 * 2.0:

那么4.0和2.0被存储为double类型,(通常)使用64位进行存储。乘积运算使用双精度,结果被载为正常的float长度。这能保证计算精度,但是会减慢程序的执行。

三、打印浮点值

printf()函数使用%f格式说明符打印十进制记数法的float和double数字,用%e打印指数记数法的数字。

程序清单3.7 showf_pt.c程序

/*showf_pt.c--以两种方式显示浮点值*/

#include<stdio.h>

int main (void)

{

float aboat = 32000.0;

double abet = 2.14e9;

long double dip = 5.32e-5;

printf ("%f can be written %e\n", aboat, aboat);

printf ("%f can be written %e\n", abet, abet );

printf ("%f can be written %e\n", dip, dip);

return 0;

}

输出结果如下:

32000.000000 can be written 3.200000e+04

2140000000.000000 can be written 2.140000e+09

2140000000.000000 can be written 2.140000e+09

上例使用了默认输出效果。下面将会讨论通过设置字段宽度和小数位来控制输出的外观。

四、浮点值的上溢和下溢

假设系统中最大的float值为3.4E38,并执行如下操作:

float toobig = 3.4E38 * 100.0f;

print ("%e\n", toobig);

会发生什么?这是一个上溢(overflow)的例子。当计算结果是一个大得不能表达的数时,会发生上溢。

浮点数舍入误差

将一个数加上1再减去原数,结果为1。如果使用浮点计算,则可能会有其他结果,如下例所示:

/*floaterr.c--说明舍入误差*/

#include<stdio.h>

int main(void)

{

float a, b;

b = 2.0e20 + 1.0;

a = b - 2.0e20;

printf("%f \n", a);

return 0;

}

程序清单3.8 typesize.c程序

/*typesize.c--输出类型的大小*/

#include<stdio.h>

int main (void)

{

/*c99为类型大小提供一个%zd说明符*/

printf("Type int has a size of %u bytex.\n",sizeof(int));

printf("Type char has a size of %u bytes.\n", sizeof(char));

printf("Type double has a size of %u bytes.\n", sizeof(long));

printf("Type double has a size of %u bytes.\n",

sizeof(double));

return 0;

}

C的内置运算符sizeof以字节为单位给出类型的大小。

Type int has a size of 4 bytex.

Type char has a size of 1 bytes.

Type double has a size of 8 bytes.

Type double has a size of 8 bytes.

使用数据类型

开发程序时,应当注意所需变量及其类型的选择。一般地,使用int或float类型表示数字,使用char类型表示字符。在使用变量的函数开始处声明该变量,并为它选择有意义的名字。初始化变量使用的常量应当同变量类型相匹配。例如:

int apples = 3; /*正确*/

int oranges =3.0; /*不好的形式*/

与Pascal语言相比,C语言对待类型不匹配现象更宽容。C编译器允许二次初始化,但是会给出警告,尤其是在您激活了较高级别警告的时候。最好不要养成这样粗心的习惯。

int cost = 12.99; /*把一个int变量初始化为一个double值*/

float pi = 3.1415926536; /*把一个float变量初始化为一个double值*/

参数和易犯的错误

有必要重复并深入介绍一下前面提到的关于printf()的使用。传递给函数的信息被称为参数。

程序清单3.9 badcount.c程序

/*badcount.c--不正确的参数个数*/

#include<stdio.h>

int main(void)

{

int f = 4;

int g = 5;

float h = 5.0f;

printf("%d\n", f, g); /*参数太多*/

printf("%d %d\n", f); /*参数太少*/

printf("%d %f\n", h, g); /*值的类型不正确*/

return 0;

}

Microsoft Visual C++7.1(Windows XP)的输出结果如下:

4

4 34603777

0 0.000000

在 Digital Mars(Windows XP)中结果为:

4

4.4239476

0 0.000000

下面是Macintosh机Metrowerks CodeWarrior Pro5的输出结果:

4

4 3327456

1075052544 0.000000

下面是Win7的输出结果:

4

4 698268176

5 5.000000

注意,使用%d显示float值不会把float值转换为近似的int值,而是显示垃圾值。与之类似,使用%f显示int值也不会把int值转换为浮点值。而且,参数的数目不足种和类型不匹配所造成的结果也将随着平台不同而不同。

另一个例子:转义序列

下面是另一个打印程序,它使用了C的一些专用转义字符。程序清单3.10演示了退格(\b)、制表符(\t)和回车符(\r)的工作方式。这些概念从计算机使用电传打字机作为输出设备时就开始使用,但它们并不一定能成功地与现代图形接口兼容。比如,此程序不能在某些Macintosh实现中正确运行。

程序清单3.10 escape.c程序

/* escape.c--使用转义字符 */

#include<stdio.h>

int main (void)

{

float salary;

printf ("\aEnter your desired monthly salary: "); /* 1 */

printf(" $___\b\b\b\b\b\b\b"); /* 2 */

scanf ("%f", &salary);

printf ("\n\t$%.2f a month is $%.2f a year.", salary, salary * 12.0); /* 3 */

printf ("\rGee!\n"); /* 4 */

return 0;

}

过程分析

假设在ANSIC环境中运行此程序,下面逐步研究此程序。第一条printf()语句(标为1的语句)发出一声警告声音(由\a产生),并打印出下列内容:

Enter your desired monthly salary:

由于字符串结尾没有\n,所以光标仍然停留在冒号后边。

第2条printf()语句紧接着前面打印,则屏幕显示如下:

Enter your desired monthly salary: $____

在冒号和美元符号之间有一个空格,因为第2条printf()语句中的字符串以空格开始。7个退格字符使光标左移7个位置,也就是把光标向左移动那7个下划线字符,使它直接紧跟在美元符的后面。通常,退格字符不删除退回时所经过的字符,但有些实现是删除的,这会和本练习有所不同。

这时,键入回答2000.00则屏幕显示为:

Enter your desired monthly salary:$2000.00

$2000.00 a month is $24000.00 a year.

由于printf()语句没有使用换行符,所以光标停留在句号后面。

第4条printf()语句以\r开始,使光标移到当前行起始位置,然后显示Gee!,接着\n使光标移到下一行的起始位置。屏幕上最后结果为:

Enter your desired monthly salary: $2000.00

Gee! $2000.00 a month is $24000.00 a year.

访问 生活导航

在本例中,我们改变超链接的文本和 URL。我们也改变 target 属性。target 属性的默认设置是 "_self",这意味着会在相同的窗口中打开链接。通过把 target 属性设置为 "_blank",链接将在新窗口中打开。