青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

C/C++圖形圖像的世界

圖形與游戲編程

常用鏈接

統計

積分與排名

Blog

最新評論

2012年1月16日 #

C/C++宏的奇技淫巧

來源:http://blog.misakamm.org/p/209
宏的主要作用就是簡化代碼編寫,簡化一些需要重復編碼的地方,以得到看起來更優雅的代碼。但宏要用得好并不容易,用的不好很容易引發災難性的后果。本文會介紹宏比較偏門但又很實用的技巧。
首先就是最常用的技巧(http://blog.misakamm.org/p/209):
#define MACROCAT( x, y ) MACROCAT1 ( x, y )
#define MACROCAT1( x, y ) x##y
#define TOSTRING( s ) #s
MACROCAT把x和y展開后連結,而TOSTRING把s轉化為字符串,比如可以printf(TOSTRING(%s), TOSTRING(abcdefg));
然后,因為宏不能遞歸,但可以做遞歸模擬,我們可以這樣玩。比如要生成n位的二進制數并且從小到大構成的字符串(用到前面的宏):
#define BIN_0(arg) TOSTRING ( arg )
#define BIN_1(arg) BIN_0(MACROCAT(arg, 0)) "," BIN_0(MACROCAT(arg, 1))
#define BIN_2(arg) BIN_1(MACROCAT(arg, 0)) "," BIN_1(MACROCAT(arg, 1))
#define BIN_3(arg) BIN_2(MACROCAT(arg, 0)) "," BIN_2(MACROCAT(arg, 1))
#define BIN_4(arg) BIN_3(MACROCAT(arg, 0)) "," BIN_3(MACROCAT(arg, 1))
int main()
{
puts(BIN_4());
return 0;
}

這里要注意的是,比如BIN_2(),實際上展開的結果是
"0" "0" "," "0" "1" "," "1" "0" "," "1" "1"
不過c/c++規定這樣連寫的字符串,編譯時就會合并成一個,于是就能用puts直接完整輸出結果了
如果你想得到更多的位,很簡單,只要你不介意,上面的宏復制并改改數字就可以了
不過,這樣一改要改若干個數字,比較麻煩,能不能讓它工作得更好?比如只要改宏名?
這個時候,就要用更富有技巧性的一招了:讓每個宏多一個參數n,然后前面的BIN_x使用MACROCAT把它與數字連結起來,不就可以了么?
想法不錯,不過問題是宏本身沒有做減法的能力,能做的僅僅是替換。減1應該怎么實現呢?
其實不難,見以下定義:
#define DECVAL_1 0
#define DECVAL_2 1
#define DECVAL_3 2
#define DECVAL_4 3
#define DECVAL_5 4
#define DECVAL_6 5
#define DECVAL_7 6
#define DECVAL_8 7
#define DECVAL_9 8
#define DECVAL( n ) DECVAL_##n
好了,有了這個利器,我們就可以對原宏改造了,先拿0號和1號宏開刀:
#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))
看得懂替換了一些什么嗎?這樣,后面的2,3,4,5號,只要復制一下1號的定義,改一改宏名就解決問題了
思考題:
這里生成的二進制結果是帶前導0的,如何改寫能使生成的結果不帶前導0?
source: http://blog.misakamm.org/p/209

使用此法可以“遞歸”式生成很多類似代碼,同時這個技巧也非常的實用,但遞歸構造并不容易,需要編寫的人仔細想清楚,否則很容易出錯,特別要注意宏展開的時機,一般不直接使用MACROCAT1宏,因為那個很可能不是你想要的結果
之后,到C99標準出臺后(也就是說,下文內容與bc3/tc/vc6不兼容),宏里面多了一個狠角色:可變參數個數宏
比如可以 #define PRINTF(...) fprintf(stdout, __VA_ARGS__)
其中__VA_ARGS__代表了‘...’部分的全部參數,這樣可以輕松的重定義庫函數里不定參數的函數的輸出行為,比如printf重定向到文件(雖然也可以用freopen實現,但只想說明宏也可以這樣搞)
好了,下文將區分編譯器來介紹,一共分為兩派,vc派和gcc派(包括clang/objc),因為兩者對以下代碼的處理并不一致,需要使用略為不同的宏來實現,目前我也只遇到這兩派。
現在的目的是這樣,因為__VA_ARGS__包含了若干參數,我怎么才能知道里面參數有多少個呢?
比如寫一個宏NUM_PARAMS(),里面寫NUM_PARAMS(abc,a,d,e)的話,替換后得到的結果要是4,能辦到嗎?
 
 
 
 
 
 
 
 
 
 
廣告時間:
http://blog.misakamm.org/p/209
廣告過后,回來精彩的節目
 
 
 
 
 
 
 
 
 
 
首先先介紹gcc派的解決方案:
#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
非常漂亮巧妙又簡潔的方案,我想不用我多解釋了吧?
不過,請注意,這是gcc的方案,以上代碼放在vc8/vc9/vc2010等都會得不到正確的結果的,這個和vc的宏處理方式有關
接下來就是給出vc的解決方案(以下均以vc2008和vc2010為準)
#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,0
這里很特別的一點是對部分小括號做了替換。
問題在于PP_NARG_到PP_ARG_N做參數傳遞的時候,如果已有顯式的括號,那么不對里面的宏做展開計算參數個數,僅直接按顯式的逗號個數判斷出參數個數,從而導致__VA_ARGS__被當成一個參數傳入。而把括號用宏替換掉后,則不出現直接的括號,就先對宏做展開,而展開后,再展開新構造出來的宏,這樣才能讓參數匹配上。
不過gcc里面不能這么干,gcc會把宏名展開出來后,如果發現后面的符號并不是顯式的括號,則把前面的宏符號化,不再展開。這兩種不同的特性讓我現在還不知道怎么編寫宏能讓兩派都能兼容,正確展開出我想要的東西。
解釋了兩個編譯器的不同點以后,后面不再解釋相同的問題,而會同時給出兩份代碼。
另一個類似的問題,就是既然有不定個數的參數,如果我希望對每個參數都做一些處理,那如何做呢?
舉例,實現一個宏#define SPREAD(...),要把參數里的東西連結成一個字符串
之前的例子里,已經實現了把不定參數展開的手段,現在我們來嘗試遞歸下降式展開(gcc版本):
#define SPREAD0( arg ) #arg
#define SPREAD1(arg, ...) SPREAD0(arg)
#define SPREAD2(arg, ...) SPREAD0(arg) SPREAD1(__VA_ARGS__,)
#define SPREAD3(arg, ...) SPREAD0(arg) SPREAD2(__VA_ARGS__,)
#define SPREAD4(arg, ...) SPREAD0(arg) SPREAD3(__VA_ARGS__,)
#define SPREAD5(arg, ...) SPREAD0(arg) SPREAD4(__VA_ARGS__,)
#define SPREAD6(arg, ...) SPREAD0(arg) SPREAD5(__VA_ARGS__,)
#define SPREAD7(arg, ...) SPREAD0(arg) SPREAD6(__VA_ARGS__,)
#define SPREAD8(arg, ...) SPREAD0(arg) SPREAD7(__VA_ARGS__,)
#define SPREAD9(arg, ...) SPREAD0(arg) SPREAD8(__VA_ARGS__,)
#define SPREAD(...) SPREAD9(__VA_ARGS__)
在這里,每進入一層,就從__VA_ARGS__拆解一個最前面的參數出來,把剩下的參數給下一層
這里有一個細節是__VA_ARGS__后面有一個逗號,意思就是補一個空參數,避免后面參數不足
然后就可以用puts(SPREAD(1, 2, 3, 4));來測試了
當然,還要使用前文的方式處理一下(gcc版):
#define SPREAD0( arg ) #arg
#define SPREAD1(n, arg, ...) SPREAD0(arg)
#define SPREAD2(n, arg, ...) SPREAD0(arg) MACROCAT(SPREAD, DECVAL(n)) ( DECVAL(n), __VA_ARGS__, )
#define SPREAD3(n, arg, ...) SPREAD0(arg) MACROCAT(SPREAD, DECVAL(n)) ( DECVAL(n), __VA_ARGS__, )
#define SPREAD4(n, arg, ...) SPREAD0(arg) MACROCAT(SPREAD, DECVAL(n)) ( DECVAL(n), __VA_ARGS__, )
#define SPREAD5(n, arg, ...) SPREAD0(arg) MACROCAT(SPREAD, DECVAL(n)) ( DECVAL(n), __VA_ARGS__, )
#define SPREAD6(n, arg, ...) SPREAD0(arg) MACROCAT(SPREAD, DECVAL(n)) ( DECVAL(n), __VA_ARGS__, )
#define SPREAD7(n, arg, ...) SPREAD0(arg) MACROCAT(SPREAD, DECVAL(n)) ( DECVAL(n), __VA_ARGS__, )
#define SPREAD8(n, arg, ...) SPREAD0(arg) MACROCAT(SPREAD, DECVAL(n)) ( DECVAL(n), __VA_ARGS__, )
#define SPREAD9(n, arg, ...) SPREAD0(arg) MACROCAT(SPREAD, DECVAL(n)) ( DECVAL(n), __VA_ARGS__, )
#define SPREAD(...) SPREAD9 ( 9, __VA_ARGS__ )
vc版:
#pragma warning(disable:4003) // 去除警告
#define SPREAD0( arg ) #arg
#define SPREAD1(n, arg, ...) SPREAD0(arg)
#define SPREAD2(n, arg, ...) SPREAD0(arg) MACROCAT(SPREAD, DECVAL(n)) BRACKET_L() DECVAL(n), __VA_ARGS__, BRACKET_R()
#define SPREAD3(n, arg, ...) SPREAD0(arg) MACROCAT(SPREAD, DECVAL(n)) BRACKET_L() DECVAL(n), __VA_ARGS__, BRACKET_R()
#define SPREAD4(n, arg, ...) SPREAD0(arg) MACROCAT(SPREAD, DECVAL(n)) BRACKET_L() DECVAL(n), __VA_ARGS__, BRACKET_R()
#define SPREAD5(n, arg, ...) SPREAD0(arg) MACROCAT(SPREAD, DECVAL(n)) BRACKET_L() DECVAL(n), __VA_ARGS__, BRACKET_R()
#define SPREAD6(n, arg, ...) SPREAD0(arg) MACROCAT(SPREAD, DECVAL(n)) BRACKET_L() DECVAL(n), __VA_ARGS__, BRACKET_R()
#define SPREAD7(n, arg, ...) SPREAD0(arg) MACROCAT(SPREAD, DECVAL(n)) BRACKET_L() DECVAL(n), __VA_ARGS__, BRACKET_R()
#define SPREAD8(n, arg, ...) SPREAD0(arg) MACROCAT(SPREAD, DECVAL(n)) BRACKET_L() DECVAL(n), __VA_ARGS__, BRACKET_R()
#define SPREAD9(n, arg, ...) SPREAD0(arg) MACROCAT(SPREAD, DECVAL(n)) BRACKET_L() DECVAL(n), __VA_ARGS__, BRACKET_R()
#define SPREAD(...) SPREAD9 BRACKET_L() 9, __VA_ARGS__, BRACKET_R()
以上只是模糊方式展開,因為參數個數不知道,后面會遇到宏參數為空的情況,于是vc編譯器給出了警告
如果把之前說的過技巧,就是分析出不定參數個數的宏,與這個結合,將產生更大的威力,我們可以實現精確展開,就是在SPREAD宏的定義里,有9的地方使用宏PP_NARG(__VA_ARGS__)替換一下,于是__VA_ARGS__后面的逗號可以去掉,也可以簡化一些代碼了,也能避免展開后有你所不希望的多余字符出現。
測試考題1:
定義一宏#define printf,讓它能把printf(str, a, b, c);替換成std::cout<<a<<b<<c<<std::endl;
參數個數不確定,不用考慮str的內容,但假設不多于10個參數

http://blog.misakamm.org/p/209
宏的威力還不止至此,當宏與C++模板編程結合的時候,真正的可怕就來臨了。。。
測試考題2:
在C++0x之前,模板還沒有不定參數,于是需要多個參數的時候,不得不手工解決,或者聰明的人,使用模板來生成多參模板代碼。嘗試一下這么做,看看和之前的問題難度加大在哪里。比如生成一個名為sum的模板函數,能接受1 - 10個參數,返回這些參數的相加的結果

 
 
 
 
 
 
 
 
 
 
 
文章附帶:
第一考題參考答案:
#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, )
測試代碼:puts(BIN_ENUM(8));
測試考題不提供答案。

posted @ 2012-01-16 16:22 御坂美琴 閱讀(7228) | 評論 (0)編輯 收藏

2011年12月27日 #

傻瓜學習C語言進制轉換

最近受網友的邀請,就寫一篇入門的教學文章。不過對于已經有一定實力水平的人來說,入門級的東西反而對于他(她)們來說不容易解釋清楚,我也想挑戰一下自己,看看我能把一些基礎問題怎么解釋能讓智商80的人也能看明白(雖然這樣說有點夸張),所以文章的標題就叫做“傻瓜學習C語言進制轉換”,不過也不是沒有要求的,要求是,看本文的時候,請你一定要按順序看,并且要確定你會寫這樣一個c程序:輸入一個int,分解出它的個位,十位,百位(提示:要用’%'求模運算和’/'整除運算)。。。。。。

1.數值與進制
數值與進制是兩個不同的東西。數值是什么?100,200這種并不是數值。
什么是數值?古代的時候,人們記數,有一個物品就記一塊石頭,或者有11個物品,就打11個繩結,這就是數值,如果你要表示1000,那你還真的需要打1000個繩結來表示。可問題就是,這樣子你會累死,為了不用累死,于是他們發明了另一種表達方式:準備兩種不同的石頭A和B,有一個,那就用一塊A石頭表示,兩個就用兩塊A表示,如果太多了,比如10個,就用一塊B石頭來表示有10個A石頭,比如AAAAABB表示25個。但是,如果表達的數值更大,那就再多準備一種石頭C,每10個B石頭就用一個C石頭來表示,比如AABCC表示212。于是,這樣就可以大大減少所需要的石頭的數目,而這,就是進制。
進制是數值的一種表示方式

2.數值與進制的轉化
進制是為了表示一個數值,如果是每10個進一,那么就是我們熟悉的10進制,否則,如果是每k個進一,那就是k進制,比如我們的時間,是每60秒記1分鐘,這就是60進制。然后,怎么把一個用特定進制的表示,得到它的數值呢?很簡單,比如上文說的AABCC,首先,有兩個A,分解得AA + BCC,就是2 + BBC,然后,1個B就是10個A,于是就是AA + AAAAAAAAAA + AAAAAAAAAA + C,然后一個C等于10個B,就是AA + AAAAAAAAAA + AAAAAAAAAA + BBBBBBBBBB,這樣一直拆下去,直到全部是A為止,你就得到實際的數值了,實際的數值就是A的個數,記住這一點,數值和進制是兩碼事。

然后,反過來,怎么把一個數值轉化為特定進制呢?很簡單,按照進制的定義,比如現在有數值AAAAAAAAAAAAAAAAAAAAAAA,然后,要轉成10進制,那么我們每10個分一分組:AAAAAAAAAA + AAAAAAAAAA + AAA,然后,把10個A用B來表示,得到:B + B + AAA,如果B有10個,那再把它換成C表示。那么,如果你明白了以上方法,你就得到一個最基本的進制轉換手段,就是先化為數值,再重新用另一個進制表示。比如10進制的13,要化成二進制,那么,就是BAAA -> AAAAAAAAAAA -> AA AA AA AA AA AA A 這時,換一個符號,每兩個A用一個M表示,那么就是MM MM MM A,再每兩個M用一個N表示,得到NN N A,再每兩個N用一個P表示,得到P N A。而在這里,一個P等于8個A,一個N等于4個A,所以P + N + A你可以驗算出8 + 4 + 1,等于原來的數值。而這種表示方法,就和羅馬數字很相似,羅馬數字里,用I表示1,用V表示5,用X表示10,于是18就用XVIII表達,用一個字母多次重復來表達一個數值。

后來,為了能更方便書寫,因為字母數量是有限的,無法表達更大的數字,書寫方式改用阿拉伯數字寫在不同的位置來表達,于是就是我們今天的10進制數字。比如剛剛的例子,BAAA,有一個B,于是在十位寫1,然后有三個B,在個位寫3,也就是B的個數,組合起來就是13,這是十進制的情況。如果是二進制,剛剛我們得到的結果是PNA,注意這里沒有M,相當于0個,而如果我們用二進制寫,那就有四個位,個位有一個A,記1,第二位相當于M的個數,是0,組合起來是01,第三位是N,記1,組合是101,第四位有一個P,再組合就是1101,于是這就是10進制的13,化為二進制的結果。

3.進制的特點
問你,3638除以10的余數是多少?給你一秒種思考時間,多少?如果這個你不能馬上說出來,那你就要反省了。結果應該是8,直接看個位不就對了。那么3638除以10的商呢?再給你一秒。。。。。。。。。。。。。。。。。。。這個答錯的話要重讀小學了,答案當然是363.8,如果把這個數取整,不要小數部分,那就是363。小學的時候你就應該知道,對一個數乘以10或者除以10這種計算是超簡單的,因為我們用的是10進制。類似的,問一下你,經過60個5秒是多少分鐘多少秒?再給你一秒思考時間,要毫不猶豫的回答我。你可別去計算60*5=300,這是多余的。答案是5分鐘,時間我們用的60進制,那么乘以60只要改一下單位就足夠了,肯定是對的。再問你,10分鐘分成60份是多少秒?你必須立即回答我是10秒。
我們推廣到任意k進制,按這個特點,k進制下,乘以k或者除以k的運算是超級簡單的,比如8進制的123,乘以8肯定是1230,除以8就是12.3,相當于在移動小數點而已。于是,k進制下乘除k就是移動小數點。而除以k求余數的話,像剛剛的8進制的123除以8,就等于12余3,就是要得到個位上的數字,同時得到原來的數舍棄掉個位的結果。這個性質非常的重要!除法的本質是什么?其實除以k是得到被除數在k進制下的個位數(余數),和小數點左移的結果(商)。

4. C下實現數值轉化為進制
好,現在回到程序,給你一個int n,要把它的各位上的數字取出來,按上面的性質,那就很簡單了,先得到個位,n%10(這個’%'是求余運算),然后小數點左移,n = n / 10; 然后不斷循環這個過程,如下代碼:

int n = 2456;
while (n > 0)
{
    printf("%d,", n % 10);
    n = n / 10;
}

輸出結果是”6,5,4,2,”,好好領悟一下這段代碼。給你五分鐘時間。每一次%10就是取出個位,每一次/10就是丟掉個位。
而如果把輸出的結果里的數字,逆過來看,就是”2456″。

在這里,那個int所表示的,就是一個數值,剛剛我們的代碼所做的事就是把這個數值,一位一位的分解出來。
而事實上,這個過程就是把數值轉化為特定進制的過程。剛剛就是把數值轉化為10進制。
如果把剛剛的代碼改為:

int n = 13;
while (n > 0)
{
    printf("%d,", n % 2);
    n = n / 2;
}

沒錯,輸出結果是”1,0,1,1″,就是剛剛把13化為二進制的例子,每一次%2就是取出二進制下的個位,每一次/2就是丟掉二進制下的個位。
只要把那個次序反過來,就得到1101,就是13化為二進制的結果。在你真正搞明白了除法的本質后,那么,數值轉化為以k進制表示那是一件很簡單的事。

5. 進制轉化為數值
這部分我不打算講,很多人對這個比起前面的內容來說容易理解很多,直接用進制的定義就已經很好辦了,沒什么太難理解的東西。

6. 作業
編寫一個程序,輸入三個整數n A B,表示把A進制的n,轉換為B進制,并輸出。
樣例:
輸入 輸出
11 8 10 9
129 10 2 10000001
22 3 6 12

假定輸入的A和B都在2-10這個范圍,超出范圍的不用去處理,輸入的n保證在int范圍內。

posted @ 2011-12-27 01:41 御坂美琴 閱讀(1466) | 評論 (1)編輯 收藏

僅列出標題  
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美日韩在线影院| 美腿丝袜亚洲色图| 国产视频一区二区三区在线观看| 欧美黄污视频| 欧美日韩成人在线播放| 欧美新色视频| 国产午夜亚洲精品理论片色戒| 国产亚洲欧美一区在线观看| 国产日韩一区在线| 精品成人免费| 日韩视频久久| 欧美在线日韩| 亚洲国产成人不卡| 亚洲精品一品区二品区三品区| 日韩午夜av电影| 久久成人综合视频| 欧美理论大片| 国产亚洲一区二区三区在线播放| 影院欧美亚洲| 亚洲一区二区三区免费视频| 久久精品一区四区| 亚洲日韩欧美视频| 欧美在线一级视频| 欧美日本网站| 国产在线一区二区三区四区| 亚洲精品欧洲精品| 久久美女性网| 中国亚洲黄色| 欧美激情精品久久久久久久变态| 国产精品五月天| 亚洲人成艺术| 久久免费99精品久久久久久| 日韩视频在线免费| 另类av导航| 狠狠88综合久久久久综合网| 中文国产成人精品久久一| 久热国产精品| 亚洲欧美国产制服动漫| 欧美日韩国产成人在线免费| 悠悠资源网久久精品| 欧美一区综合| 亚洲一区二区网站| 欧美精品日韩| 在线免费日韩片| 久久精品国亚洲| 亚洲无玛一区| 国产精品vvv| 在线午夜精品自拍| 亚洲激情av| 老司机午夜免费精品视频 | 亚洲欧美一区二区三区极速播放| 免费观看日韩av| 在线观看欧美亚洲| 久久性天堂网| 亚洲欧美日韩一区二区三区在线观看 | 六月婷婷久久| 国产一区二区三区在线观看视频| 亚洲欧美成人网| 一本色道久久88综合日韩精品| 美腿丝袜亚洲色图| 最新国产の精品合集bt伙计| 欧美高清视频一区二区三区在线观看 | 国产一区二区三区在线观看免费视频| 中日韩视频在线观看| 亚洲免费播放| 国产精品久久久久久久久果冻传媒 | 国产精品国色综合久久| 亚洲永久网站| 亚洲一区二区综合| 国产日韩一区| 牛夜精品久久久久久久99黑人| 久久久国产精品亚洲一区 | 国产日韩av在线播放| 欧美在线一区二区三区| 性色av一区二区三区在线观看| 国产精品夜夜夜一区二区三区尤| 亚洲欧美日韩国产综合| 亚洲欧美日韩国产综合在线 | 久久大逼视频| 亚洲第一色在线| 最新成人av网站| 国产精品黄色在线观看| 久久精品2019中文字幕| 久久青草久久| 亚洲视频axxx| 欧美主播一区二区三区| 亚洲激情视频在线| av成人国产| 激情五月婷婷综合| 亚洲精品一区二区三区婷婷月 | 免费国产自线拍一欧美视频| 日韩午夜视频在线观看| 亚洲一级黄色| 亚洲国语精品自产拍在线观看| 亚洲精品四区| 精品不卡一区| 亚洲在线成人精品| 91久久线看在观草草青青| 亚洲天堂av在线免费观看| 精品999成人| 99国产精品99久久久久久| 狠色狠色综合久久| 亚洲视频电影图片偷拍一区| 136国产福利精品导航网址应用| 99视频精品免费观看| 精品99视频| 午夜视频一区二区| 亚洲小说区图片区| 欧美www视频在线观看| 久久精品国产久精国产爱| 欧美日韩一区高清| 欧美国产另类| 国产欧美一区二区三区沐欲| 亚洲电影观看| 狠狠色丁香婷婷综合影院| 在线视频亚洲| 日韩西西人体444www| 久久久久久久久一区二区| 午夜精品www| 欧美日韩一区在线视频| 欧美寡妇偷汉性猛交| 黑人一区二区三区四区五区| 亚洲免费在线视频| 亚洲一区日本| 欧美日韩亚洲一区二区| 亚洲黄色三级| 亚洲精选成人| 欧美激情视频一区二区三区免费| 久久夜色精品国产欧美乱| 国产女优一区| 午夜亚洲福利| 欧美在线一二三| 国产日韩精品久久久| 性欧美video另类hd性玩具| 亚洲欧美激情一区二区| 国产精品久久久久aaaa九色| 中文在线资源观看网站视频免费不卡| 日韩午夜激情| 欧美日韩一区精品| 亚洲夜间福利| 久久国产精品亚洲va麻豆| 国产精品一卡| 久久精品国产一区二区三区| 久久久久九九九| 在线观看亚洲一区| 另类激情亚洲| 亚洲看片免费| 亚洲欧美日韩精品久久奇米色影视| 欧美日韩一二三四五区| 一本一本久久a久久精品牛牛影视| 亚洲图色在线| 国产精品专区第二| 久久久国产精彩视频美女艺术照福利| 男人的天堂成人在线| 亚洲国产精品第一区二区三区| 欧美jizzhd精品欧美喷水| 亚洲毛片av在线| 欧美一区二区在线看| 红桃视频欧美| 欧美日韩综合另类| 久久精品国产一区二区三| 亚洲国产乱码最新视频| 亚洲一区国产视频| 激情久久影院| 欧美日韩亚洲另类| 久久久久国产精品一区| 亚洲黄色在线观看| 欧美中文在线视频| 亚洲欧洲日本mm| 国产精品久久久久久久9999| 久久久国产精品一区二区中文| 亚洲国产另类 国产精品国产免费| 亚洲欧美日韩在线综合| 亚洲电影欧美电影有声小说| 欧美日本不卡| 久久九九国产精品怡红院| 亚洲精品久久久久久一区二区| 午夜一区二区三视频在线观看| 在线高清一区| 国产精品午夜国产小视频| 欧美国产日韩a欧美在线观看| 亚洲欧美国产另类| 日韩亚洲精品视频| 欧美 日韩 国产精品免费观看| 夜夜嗨一区二区| 激情另类综合| 国产日产高清欧美一区二区三区| 欧美精品免费播放| 久久一区二区三区四区| 亚洲永久免费观看| 亚洲精品日产精品乱码不卡| 久久久久青草大香线综合精品| 亚洲一二三四区| 99在线精品视频| 亚洲黄色大片| 亚洲大黄网站| 曰韩精品一区二区| 国产一区二区久久久| 国产精品欧美精品| 欧美视频一区二区三区…|