prev up next   top/contents search

comp.lang.c FAQ 列表· 第 20.10 题

如何将整数转换为二进制或十六进制?


请务必清楚你真正要问的是什么。整数在内部存储为二进制,虽然对于大多数用途来说,将它们视为八进制、十进制或十六进制(取决于方便)也并非不正确。数字所表示的基数仅在数字从外部世界读入或写入时才重要,无论是作为源代码常量还是程序执行的 I/O。

在源代码中,非十进制基数由前导00x(分别表示八进制或十六进制)指示。在 I/O 期间,格式化数字的基数由 `printf`printf`scanf`系列函数中的格式说明符(`%d`%d, `%o`, `%x`等)和 `strtol`strtol`strtoul`函数中的第三个参数控制。然而,在 *二进制* I/O 期间,基数再次变得无关紧要:如果数字是作为单个字节(通常使用 `getc`getc`putc`)或多字节字(通常使用 `fread`fread`fwrite`)读取或写入,那么询问它们是“什么基数”就没有意义了。

如果你需要的是格式化的二进制转换,这很容易做到。下面是一个用于以请求的基数格式化数字的小函数

char *
baseconv(unsigned int num, int base)
{
	static char retbuf[33];
	char *p;

	if(base < 2 || base > 16)
		return NULL;

	p = &retbuf[sizeof(retbuf)-1];
	*p = '\0';

	do {
		*--p = "0123456789abcdef"[num % base];
		num /= base;
	} while(num != 0);

	return p;
}
(请注意,此函数按原样编写,它返回一个指向静态数据的指针,因此一次只能使用其返回值的其中一个;请参阅问题 7.5a。`retbuf`retbuf数组的更好大小是 `sizeof(int)*CHAR_BIT+1`sizeof(int)*CHAR_BIT+1;请参阅问题 12.21。)

有关“二进制”I/O 的更多信息,请参阅问题 2.11、12.37 和 12.42。另请参阅问题 8.6 和 13.1。

附加链接:我发送给一位询问如何编写“二进制到十进制”转换函数的人的长回复

参考:ISO Secs. 7.10.1.5,7.10.1.6


prev up next   contents search
关于此 FAQ 列表   关于 Eskimo   搜索   反馈   版权

Eskimo North 托管