"0" "0" "," "0" "1" "," "1" "0" "," "1" "1"不过c/c++规定q样q写的字W串Q编译时׃合ƈ成一个,于是p用puts直接完整输出l果?br /> 如果你想得到更多的位Q很单,只要你不介意Q上面的宏复制ƈҎ数字可以了
#define BIN_0(n, arg) TOSTRING ( arg ) #define BIN_1(n, arg) MACROCAT(BIN_, DECVAL(n)) (DECVAL(n), MACROCAT(arg, 0)) \ "," MACROCAT(BIN_, DECVAL(n)) (DECVAL(n), MACROCAT(arg, 1))看得懂替换了一些什么吗Q这P后面?,3,4,5P只要复制一?L定义Q改一改宏名就解决问题?br /> 思考题Q?br /> q里生成的二q制l果是带前导0的,如何改写能生成的结果不带前?Q?br /> source: http://blog.misakamm.org/p/209
#define PP_NARG(...) PP_NARG_(__VA_ARGS__, PP_RSEQ_N()) #define PP_NARG_(...) PP_ARG_N(__VA_ARGS__) #define PP_ARG_N( \ _1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \ _11,_12,_13,_14,_15,_16, N, ...) N#define PP_RSEQ_N() \ 16,15,14,13,12,11,10, \ 9,8,7,6,5,4,3,2,1,0 非常漂亮巧妙又简z的ҎQ我想不用我多解释了吧?
#define BRACKET_L() ( #define BRACKET_R() ) #define PP_NARG(...) \ PP_NARG_ ( __VA_ARGS__, PP_RSEQ_N() ) #define PP_NARG_(...) \ PP_ARG_N BRACKET_L() __VA_ARGS__ BRACKET_R() #define PP_ARG_N( \ _1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \ _11,_12,_13,_14,_15,_16, N,...) N #define PP_RSEQ_N() \ 16,15,14,13,12,11,10, \ 9,8,7,6,5,4,3,2,1,0q里很特别的一Ҏ寚w分小括号做了替换?br /> 问题在于PP_NARG_到PP_ARG_N做参C递的时候,如果已有昑ּ的括P那么不对里面的宏做展开计算参数个数Q仅直接按显式的逗号个数判断出参C敎ͼ从而导致__VA_ARGS__被当成一个参C入。而把括号用宏替换掉后Q则不出现直接的括号Q就先对宏做展开Q而展开后,再展开新构造出来的宏,q样才能让参数匹配上?br /> 不过gcc里面不能q么qԌgcc会把宏名展开出来后,如果发现后面的符号ƈ不是昑ּ的括P则把前面的宏W号化,不再展开。这两种不同的特性让我现在还不知道怎么~写宏能让两zN能兼容,正确展开出我惌的东ѝ?br /> 解释了两个编译器的不同点以后Q后面不再解释相同的问题Q而会同时l出两䆾代码?br /> 另一个类似的问题Q就是既然有不定个数的参敎ͼ如果我希望对每个参数都做一些处理,那如何做呢?
#define BINARY_E0(n, arg) TOSTRING ( arg ) #define BINARY_E1(n, arg) MACROCAT(BINARY_E, DECVAL(n)) ( DECVAL(n), MACROCAT(arg, 0) )\ "," MACROCAT(BINARY_E, DECVAL(n)) ( DECVAL(n), MACROCAT(arg, 1) ) #define BINARY_E2(n, arg) MACROCAT(BINARY_E, DECVAL(n)) ( DECVAL(n), MACROCAT(arg, 0) )\ "," MACROCAT(BINARY_E, DECVAL(n)) ( DECVAL(n), MACROCAT(arg, 1) ) #define BINARY_E3(n, arg) MACROCAT(BINARY_E, DECVAL(n)) ( DECVAL(n), MACROCAT(arg, 0) )\ "," MACROCAT(BINARY_E, DECVAL(n)) ( DECVAL(n), MACROCAT(arg, 1) ) #define BINARY_E4(n, arg) MACROCAT(BINARY_E, DECVAL(n)) ( DECVAL(n), MACROCAT(arg, 0) )\ "," MACROCAT(BINARY_E, DECVAL(n)) ( DECVAL(n), MACROCAT(arg, 1) ) #define BINARY_E5(n, arg) MACROCAT(BINARY_E, DECVAL(n)) ( DECVAL(n), MACROCAT(arg, 0) )\ "," MACROCAT(BINARY_E, DECVAL(n)) ( DECVAL(n), MACROCAT(arg, 1) ) #define BINARY_E6(n, arg) MACROCAT(BINARY_E, DECVAL(n)) ( DECVAL(n), MACROCAT(arg, 0) )\ "," MACROCAT(BINARY_E, DECVAL(n)) ( DECVAL(n), MACROCAT(arg, 1) ) #define BINARY_E7(n, arg) MACROCAT(BINARY_E, DECVAL(n)) ( DECVAL(n), MACROCAT(arg, 0) )\ "," MACROCAT(BINARY_E, DECVAL(n)) ( DECVAL(n), MACROCAT(arg, 1) ) #define BINARY_E8(n, arg) MACROCAT(BINARY_E, DECVAL(n)) ( DECVAL(n), MACROCAT(arg, 0) )\ "," MACROCAT(BINARY_E, DECVAL(n)) ( DECVAL(n), MACROCAT(arg, 1) ) #define BINARY_ENUM(n) MACROCAT(BINARY_E, n) ( n, ) #define BIN_0(n, arg) TOSTRING ( arg ) #define BIN_1(n, arg) MACROCAT(BIN_, DECVAL(n)) (DECVAL(n), arg) \ "," MACROCAT(BINARY_E, DECVAL(n)) (DECVAL(n), MACROCAT(arg, 1)) #define BIN_2(n, arg) MACROCAT(BIN_, DECVAL(n)) (DECVAL(n), arg) \ "," MACROCAT(BINARY_E, DECVAL(n)) (DECVAL(n), MACROCAT(arg, 1)) #define BIN_3(n, arg) MACROCAT(BIN_, DECVAL(n)) (DECVAL(n), arg) \ "," MACROCAT(BINARY_E, DECVAL(n)) (DECVAL(n), MACROCAT(arg, 1)) #define BIN_4(n, arg) MACROCAT(BIN_, DECVAL(n)) (DECVAL(n), arg) \ "," MACROCAT(BINARY_E, DECVAL(n)) (DECVAL(n), MACROCAT(arg, 1)) #define BIN_5(n, arg) MACROCAT(BIN_, DECVAL(n)) (DECVAL(n), arg) \ "," MACROCAT(BINARY_E, DECVAL(n)) (DECVAL(n), MACROCAT(arg, 1)) #define BIN_6(n, arg) MACROCAT(BIN_, DECVAL(n)) (DECVAL(n), arg) \ "," MACROCAT(BINARY_E, DECVAL(n)) (DECVAL(n), MACROCAT(arg, 1)) #define BIN_7(n, arg) MACROCAT(BIN_, DECVAL(n)) (DECVAL(n), arg) \ "," MACROCAT(BINARY_E, DECVAL(n)) (DECVAL(n), MACROCAT(arg, 1)) #define BIN_8(n, arg) MACROCAT(BIN_, DECVAL(n)) (DECVAL(n), arg) \ "," MACROCAT(BINARY_E, DECVAL(n)) (DECVAL(n), MACROCAT(arg, 1)) #define BIN_ENUM(n) "0" MACROCAT(BIN_, n) ( n, ) 试代码Qputs(BIN_ENUM(8)); 试考题不提供答案?
最q受|友的邀P写一入门的教学文章。不q对于已l有一定实力水q的人来_入门U的东西反而对于他Q她Q们来说不容易解释清楚,我也x战一下自己,看看我能把一些基问题怎么解释能让智商80的h也能看明白(虽然q样说有点夸张)Q所以文章的标题叫?#8220;ȝ学习C语言q制转换”Q不q也不是没有要求的,要求是,看本文的时候,请你一定要按顺序看Qƈ且要定你会写这样一个cE序Q输入一个intQ分解出它的个位Q十位,百位Q提C:要用’%'求模q算?#8217;/'整除q算Q。。。。。?br />
1.数gq制
数gq制是两个不同的东西。数值是什么?100Q?00q种q不是数倹{?br />
什么是数|古代的时候,Z记数Q有一个物品就C块石_或者有11个物品,打11个Ѿl,q就是数|如果你要表示1000Q那你还真的需要打1000个Ѿl来表示。可问题是Q这样子你会累死Qؓ了不用篏死,于是他们发明了另一U表达方式:准备两种不同的石头A和BQ有一个,那就用一块A矛_表示Q两个就用两块A表示Q如果太多了Q比?0个,q一块B矛_来表C有10个A矛_Q比如AAAAABB表示25个。但是,如果表达的数值更大,那就再多准备一U石头CQ每10个B矛_q一个C矛_来表C,比如AABCC表示212。于是,q样可以大大减所需要的矛_的数目,而这Q就是进制?br />
q制是数值的一U表C方?/p>
2.数gq制的{?br /> q制是ؓ了表CZ个数|如果是每10个进一Q那么就是我们熟悉的10q制Q否则,如果是每k个进一Q那是kq制Q比如我们的旉Q是?0U记1分钟Q这是60q制。然后,怎么把一个用特定q制的表C,得到它的数值呢Q很单,比如上文说的AABCCQ首先,有两个AQ分解得AA + BCCQ就? + BBCQ然后,1个B是10个AQ于是就是AA + AAAAAAAAAA + AAAAAAAAAA + CQ然后一个C{于10个BQ就是AA + AAAAAAAAAA + AAAAAAAAAA + BBBBBBBBBBQ这样一直拆下去Q直到全部是A为止Q你得到实际的数gQ实际的数值就是A的个敎ͼCq一点,数值和q制是两码事?/p>
然后Q反q来Q怎么把一个数D{化ؓ特定q制呢?很简单,按照q制的定义,比如现在有数值AAAAAAAAAAAAAAAAAAAAAAAQ然后,要{?0q制Q那么我们每10个分一分组QAAAAAAAAAA + AAAAAAAAAA + AAAQ然后,?0个A用B来表C,得到QB + B + AAAQ如果B?0个,那再把它换成C表示。那么,如果你明白了以上ҎQ你得C个最基本的进制{换手D,是先化为数|再重新用另一个进制表C。比?0q制?3Q要化成二进Ӟ那么Q就是BAAA -> AAAAAAAAAAA -> AA AA AA AA AA AA A q时Q换一个符P每两个A用一个M表示Q那么就是MM MM MM AQ再每两个M用一个N表示Q得到NN N AQ再每两个N用一个P表示Q得到P N A。而在q里Q一个P{于8个AQ一个N{于4个AQ所以P + N + A你可以验出8 + 4 + 1Q等于原来的数倹{而这U表C方法,和|马数字很相||马数字里,用I表示1Q用V表示5Q用X表示10Q于?8qXVIII表达Q用一个字母多ơ重复来表达一个数倹{?/p>
后来Qؓ了能更方便书写,因ؓ字母数量是有限的Q无法表达更大的数字Q书写方式改用阿拉伯数字写在不同的位|来表达Q于是就是我们今天的10q制数字。比如刚刚的例子QBAAAQ有一个BQ于是在十位?Q然后有三个BQ在个位?Q也是B的个敎ͼl合h是13Q这是十q制的情c如果是二进Ӟ刚刚我们得到的结果是PNAQ注意这里没有MQ相当于0个,而如果我们用二进制写Q那有四个位,个位有一个AQ记1Q第二位相当于M的个敎ͼ?Q组合v来是01Q第三位是NQ记1Q组合是101Q第四位有一个PQ再l合是1101Q于是这是10q制?3Q化Zq制的结果?/p>
3.q制的特?br /> 问你Q?638除以10的余数是多少Q给你一U种思考时_多少Q如果这个你不能马上说出来,那你p反省了。结果应该是8Q直接看个位不就对了。那?638除以10的商呢?再给你一U。。。。。。。。。。。。。。。。。。。这个答错的话要重读学了,{案当然?63.8Q如果把q个数取_不要数部分Q那是363。小学的时候你应该知道,对一个数乘以10或者除?0q种计算是超单的Q因为我们用的是10q制。类似的Q问一下你Q经q?0?U是多少分钟多少U?再给你一U思考时_要毫不犹豫的回答我。你可别去计?0*5=300Q这是多余的。答案是5分钟Q时间我们用?0q制Q那么乘?0只要改一下单位就_了,肯定是对的。再问你Q?0分钟分成60份是多少U?你必ȝ卛_{我?0U?br /> 我们推广CQ意kq制Q按q个特点Qkq制下,乘以k或者除以k的运是单的Q比?q制?23Q乘?肯定?230Q除?是12.3Q相当于在移动小数点而已。于是,kq制下乘除k是Ud数炏V而除以k求余数的话,像刚刚的8q制?23除以8Q就{于12?Q就是要得到个位上的数字Q同时得到原来的数舍弃掉个位的结果。这个性质非常的重要!除法的本质是什么?其实除以k是得到被除数在kq制下的个位敎ͼ余数Q,和小数点左移的结果(商)?/p>
4. C下实现数D{化ؓq制
好,现在回到E序Q给你一个int nQ要把它的各位上的数字取出来Q按上面的性质Q那很单了Q先得到个位Qn%10Q这?#8217;%'是求余运)Q然后小数点左移Qn = n / 10; 然后不断循环q个q程Q如下代码:
int n = 2456; while (n > 0) { printf("%d,", n % 10); n = n / 10; }
输出l果?#8221;6,5,4,2,”Q好好领悟一下这D代码。给你五分钟旉。每一?10是取出个位Q每一?10是丢掉个位?br /> 而如果把输出的结果里的数字,逆过来看Q就?#8221;2456″?/p>
在这里,那个int所表示的,是一个数|刚刚我们的代码所做的事就是把q个数|一位一位的分解出来?br /> 而事实上Q这个过E就是把数D{化ؓ特定q制的过E。刚刚就是把数D{化ؓ10q制?br /> 如果把刚刚的代码改ؓQ?/p>
int n = 13; while (n > 0) { printf("%d,", n % 2); n = n / 2; }
没错Q输出结果是”1,0,1,1″Q就是刚刚把13化ؓ二进制的例子Q每一?2是取出二进制下的个位,每一?2是丢掉二进制下的个位?br /> 只要把那个次序反q来Q就得到1101Q就?3化ؓ二进制的l果。在你真正搞明白了除法的本质后,那么Q数D{化ؓ以kq制表示那是一件很单的事?/p>
5. q制转化为数?br /> q部分我不打讲Q很多h对这个比起前面的内容来说Ҏ理解很多Q直接用q制的定义就已经很好办了Q没什么太隄解的东西?/p>
6. 作业
~写一个程序,输入三个整数n A BQ表C把Aq制的nQ{换ؓBq制Qƈ输出?br />
样例Q?br />
输入 输出
11 8 10 9
129 10 2 10000001
22 3 6 12
假定输入的A和B都在2-10q个范围Q超围的不用d理,输入的n保证在int范围内?/p>