这是将数字转换为八进制,十进制,十六进制等不同表示的程序.
#include<stdio.h>
char *convert(unsigned int num, int base)
{
static char buff[33];
char *ptr;
ptr=&buff[sizeof(buff)-1];
*ptr='\0';
do
{
*--ptr="0123456789abcdef"[num%base];
num/=base;
}while(num!=0);
return(ptr);
}
int main(){
puts(convert(65,8));
puts(convert(65,10));
puts(convert(65,16));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出给出101,65和41(即数字'65'分别以八进制,十进制和十六进制表示)
我非常了解最新情况,但我从来没有遇到过类似的事情
*--ptr="0123456789abcdef"[num%base]
Run Code Online (Sandbox Code Playgroud)
我理解它的工作,但我不明白它是如何有效的符号.有人请在这里解释0123456789abcdef(文字字符数组)部分.
这是一件可怕的工作; 任何人都应该把它写在棚子的后面并被殴打,直到他们承诺永远不会再在IOCCC(国际混淆C代码竞赛)的条目之外再写这样的代码.
表达的右侧
*--ptr = "0123456789abcdef"[num%base];
Run Code Online (Sandbox Code Playgroud)
正在利用字符串文字转换为指针的事实.如果你看到:
const char digit[] = "0123456789ABCDEF";
*--ptr = digit[num%base];
Run Code Online (Sandbox Code Playgroud)
你不会担心.字符串文字的表达式与此相同.(至少他们有恩典不写:
*--ptr = (num % base)["0123456789ABCDEF"];
Run Code Online (Sandbox Code Playgroud)
这也与以下关系相同:
a[i] <==> i[a] <==> *(a + i) <==> *(i + a)
Run Code Online (Sandbox Code Playgroud)
其中双头箭头表示等效.
使用*--ptr是向后提取数字,从最小到最重要.它的工作原理是因为指针被初始化为静态缓冲区的末尾(并且由于函数的返回值是指向该缓冲区的指针,所以它是静态的至关重要).
但是,代码不是很有用,因为您无法保存呼叫中的值,并在以后再次打印时打印它.你不能写:
printf("%s = %s = %sn", convert(65,8), convert(65,10), convert(65,16));
Run Code Online (Sandbox Code Playgroud)
或者,更准确地说,你可以,但你会在第一个位置看到"101","164"或"140" 三次相同的值,并且"01"或"64"或"40"的值相同其他两个位置,C标准没有定义您将看到的值.静态缓冲区还可以防止代码是线程安全的.
总而言之,这是一个奇怪的炫耀代码,用于挑逗初学者.它有效,但这就是关于它的所有可以说的.它也没有检查其基础的有效性,因此convert(65, 18)可能导致未定义的行为.(在最坏的情况下,基数17会引用一个'\0'无意的,导致混淆.)