# 1. 迴圈依賴 ## 1.1 什麼是迴圈依賴 首先,什麼是迴圈依賴?這個其實好理解,就是兩個 Bean 互相依賴,類似下麵這樣: """ @Service public class AService { @Autowired BService bService; } @Service publi ...
進位轉換:
1、為什麼使用二進位、八進位、十六進位?
因為目前的CPU只能識別高低兩種電平,只能對二進位數據進行計算
二進位雖然能夠直接被電腦識別,但是不方便人去書寫和記錄,因此就把二進位數據轉換成八進位,方便記錄到文檔中
隨著CPU的位數的不斷增加,已經到目前的64位,所以八進位不再能夠滿足需求,因此發展出現在的十六進位,由於歷史原因八進位還不能退出歷史舞臺
2、十進位轉二進位(其它進位)
求餘法:
用2不停地對數據求餘,然後繼續對商求餘,直到商為0結束,在過程中得到的餘數(逆序)就是該數據的二進位
127 % 2 1
63 % 2 1
31 % 2 1
15 % 2 1
7 % 2 1
3 % 2 1
1 % 2 1
0
0111 1111
求權法:
讓數據從高位n位開始,數據 - 2^(n-1) ,如果夠減,那麼第n位為1,否則為0,直到減完為止
134
128 64 32 16 8 4 2 1
1 0 0 0 0 1 1 0
手算:73 62 121 49
練習1:輸入一個正整數m,然後輸入n(n>=2),顯示m的n進位結果,超過10的位用字母表示
10 A 11 B 12 C ...
gcc xxx.c && ./a.out
3、二進位轉十進位
每位乘以權位2^(n-1),求和
10011001 128+16+8+1
4、二進位轉八進位
從低位起,每三個二進位位對應一個八進位位
二進位:10 101 110 111 100
八進位:2 5 6 7 4
5、二進位轉十六進位
從低位起,每四個二進位位對應一個十六進位位
二進位: 10 1011 1011 1100
十六進位: 2 B B C
6、不同進位在程式的顯示:
在C代碼中,以0開頭的數據是八進位數據,以0x/0X開頭的是十六進位數據
%x 讓數據以十六進位顯示
%o 讓數據以八進位顯示
%#x %#o 顯示出數據對應的進位首碼
7、原碼、反碼、補碼
原碼:數據的二進位
反碼:
正數的原碼就是反碼
負數的反碼是:它的原碼符號位不變,其它位按位求反
補碼:
所有數據在電腦中,都是以補碼形式存儲
正數的原碼就是補碼
負數的補碼:
1、轉換成二進位,得到原碼
2、原碼符號位不變,其餘按位求反,得到反碼
3、反碼+1,得到補碼
-127
1111 1111 原碼
1000 0000 反碼
1000 0001 補碼
8、補碼如何轉成數據:
先確定是有符號還是無符號
1、無符號\有符號且最高位為0,補碼直接轉成十進位
2、有符號的且最高位為1
a、補碼-1,得到反碼
b、符號位不變,其餘位按位求反,得到原碼
c、原碼轉十進位數
1111 1111 補碼
1111 1110 反碼
1000 0001 原碼
-1
127+1 = -128
0111 1111 + 1
1000 0000 -128
for(uint8_t i=0; i<256; i++)
{
printf("a");
}
位運算符:
& | ~ ^ << >>
A & B 按位相與
1010 1110 A 0xAE
0111 1100 B 0x7C
--------------
0010 1100 C 0x2C
A | B 按位相或
1010 1110 A 0xAE
0111 1100 B 0x7C
--------------
1111 1110 C
~A 按位求反
1010 1110 A 0xAE
-----------
0101 0001
A ^ B 按位異或 相同為零,相異為一(口訣:異或求一,同或求零)
1010 1110 A 0xAE
0111 1100 B 0x7C
--------------
1101 0010
A << n 按位左移n位,左邊超出的丟棄,右邊補0
1010 1110 A << 3
0111 0000
A >> n 按位右移n位,右邊超出的丟棄,左邊補符號位(這點很重要,補的是符號位)
1010 1110 A >> 3
1111 0101
註意:只要式子中出現了位運算符,必須轉換成二進位補碼再進行運算
函數:Function
一段具有某一項功能的代碼集合,是C語言管理代碼的最小單位
把代碼封裝成一個個函數,方便管理和調用代碼
1、函數分類:
標準庫函數:
C語言標準委員會以函數形式提供的一些基礎功能,都被封裝在libc.so庫中,並且分在了不同的文件中,需要使用時只要把對應的頭文件導入即可(例如stdio.h...),然後通過具體的 函數名(參數) 即可完成調用
#include <time.h>
time_t time(time_t *tloc);
功能:獲取自1970-1-1 0:0:0 到調用時總共過了的秒數
用法:time_t sec = time(NULL);
#include <stdlib.h>
int rand(void);
功能:獲取一個隨機數
註意:目前任何編程語言和系統都沒有真正的隨機數,C編譯器是把從0~極大值範圍的數值打亂後,存儲到一塊固定記憶體中,然後從裡面取所謂的隨機數
void srand(unsigned int seed);
功能:種隨機種子,設置從隨機數記憶體的某個位置開始取隨機數,為了實現類似真隨機的效果,seed位置一般使用time(NULL)來設置
int system(const char *command);
功能:執行系統命令command
例如:system("clear");
練習3:獲取10個範圍[100,1000]之間的隨機數,獲取次數不能超過10次
rand()%901 + 100 [a,b]
rand()%(b-a+1) +a
練習4:雙色球規則:6個紅球範圍1-33 1個藍球範圍1-16
通過程式產生一組隨機的中獎號碼:紅球不能重覆
rand()%33+1
rand()%16+1
系統函數:
是操作系統以函數形式提供的一些功能介面
但是系統函數不是真正的函數
第三方庫函數:
一些開源或收費的第三方代碼
GitHub
md5
JSON 序列化和反序列化
100 "100" "100" 100
glog 谷歌日誌系統
XML 配置文件解析程式
自定義函數:
為了更好地管理代碼,減少代碼冗餘,把代碼封裝成自定義函數
函數聲明:
函數聲明的目的為了告訴其他的調用者,該函數的調用格式
返回值類型 函數名(形參類型1 形參名,形參類型2 形參名,...);
1、C語言中函數名一般全部小寫,可以用下劃線分隔
2、如果不需要參數時,建議寫void,不要空著
3、如果沒有返回值,就寫void
函數定義:
函數的具體實現
返回值類型 函數名(形參類型1 形參名,形參類型2 形參名,...)
{
// 函數體
return [val];
}
函數調用:
函數名(實參1,實參2);
註意:返回值會放在調用函數語句這裡,應該用變數接收或者直接顯示,否則再也拿不到
使用函數需要註意的問題:
函數的隱式聲明:
在函數調用前沒有任何該函數的聲明或定義,那麼就會產生隱式聲明
要避免產生隱式聲明,那麼就需要在函數調用前有函數聲明或函數定義
註意:如果在函數調用前完成了函數的定義,那麼函數聲明可以省略