随笔1:程序
什么是程序?
軟件還包括數據和文檔;軟件=程序+數據+文檔;
輸入設備:鍵盤鼠標;輸出設備:顯示器;存儲器:存代碼和設備;CPU(中央處理器):控制器(控制存取的一些指令層)和運算器(進行數據的處理);計算機把可執(zhí)行的代碼通過輸入設備讀到內存里,然后CPU來運行這些代碼,讀取這些相關的輸入數據,然后再把這個計算出來的輸出數據輸出完成程序的預定功能。
CPU:相當于人的大腦;存儲器:是一種記憶裝置;輸入輸出設備:相當于人的眼睛和耳朵。
11/5=2;11.0/5=2.2;浮點數可以做除法運算)但是求余比較特殊:只能用整數作為他的操作數,也就是兩個數求余這兩個數必須是整數。
?
scanf("%lf",&a);//后邊為什么是取地址,因為是讀入函數,我讀入a的值你要告訴我往哪存儲啊,所以告訴我一個地址。
程序中直接使用的常數,稱為幻數。(我們不提倡直接在程序當中直接使用常數的,因為多次修改或者多處修改可能會出錯。)
解決辦法就是把這個幻數定義為常量,宏常量;或者說是const常量。
宏常量定義:
#define 標識符 字符串//標識符是定義的宏常量的宏名,字符串是那個值
在程序中使用宏替換。
定義為const常量:?
單精度賦值給雙精度浮點數:
?
雙精度浮點數賦值給單精度浮點數:
雙精度浮點數他的精度高,也就是他的小數占的位數多,有效數字位數多;如果說你的雙精度浮點數有效位數很多,你現在賦值給單精度,單精度浮點數他的有效位數不會超過7,所以多余的那些小數位信息就丟失了。
比如是一個雙精度的實型常數,雙精度實型常數你賦值給雙精度實型變量,所以這個結果不會有問題,精度不會損失;但是你把一個雙精度實型常量賦值給一個單精度實型的變量,因為單精度實型變量他的有效位數不會超過7,那你多余的超過7位之后的那些數字,雖然也輸出了但是他是不可靠的,所以發(fā)生有精度損失。
解決辦法:用類型強轉可以消除類型轉換的警告。(意思就是把表達式的值轉換成你希望得到的那個類型)
//轉換方法
(類型)表達式;//把這個表達式的值轉換成我希望的類型
注意:類型強轉并不改變后面的這個變量的類型,他只是把變量的值轉換成你指定的這個類型,但是變量的類型并沒有改變,所以x的類型并沒有變化。
兩個整數相除得到的商只能是整數,所以通過強轉來得到實數:
此處雖然你的average聲明為實型而已,只不過是在后邊添加0而已。?
第一個輸出:m除2的結果是整數除法;
第二個輸出:是對m/2的結果進行強轉;因為加了一個括號,m/2的結果就是2,對2進行強轉成flaot類型,只不過就是2.000000;
第三個輸出:是對m進行強轉,把5強轉成5.000000,之后與2進行做除法就是2.5;
第四個輸出:驗證m的值有沒有改變;沒有m的值打印出來還是5。
'\n'表示換行;如果加一個r‘\r’就表示回車不換行;回車不換行和換行的區(qū)別:輸出一行之后光標停在末尾,如果用'\n'換一下行光標移到下一行的起始位置;如果說回車不換行的話,光標移到依然是本行的起始位置,并不到下一行,再次輸出會把這一行給覆蓋掉。
以百分號開始的是一個轉換說明。
格式化輸出函數:
前邊加上負號之后是左對齊,右補空格。
后邊是7位小數,但是我們的f輸出只能輸出6位小數,所以會對它進行四舍五入取整。所以6位小數加上一個小數位再加上前面兩位,一共是占了9位,我們指定的寬度是10位,10大于你實際輸出的那個寬度,意味著我們要補空格,所以是右對齊左補空格。
自控制小數位數:
實際寬度就是3位小數,不需要補空格。
格式化輸入函數:
輸出數據的時候是不區(qū)分單精度和雙精度都是%f,輸入數據的時候就要區(qū)分了,單精度實型就要%f,雙精度實型就要在f的前邊加上一個小寫的字母l,即%lf。
提問:為什么用%lf來讀入雙精度實型數,而用%f來輸出呢?
解釋:在調用可變長度參數表的時候,這個編譯器會將單精度實型自動轉化為double雙精度實型,所以這個printf沒有辦法區(qū)分這個是單精度還是雙精度的實型,因為他把單精度實型自動轉化為雙精度實型來輸出;為什么輸入的時候就要指定單精度還是雙精度了呢?這是因為scanf它后邊的不是一個輸出項表,而是一個輸入地址表,要指定的地址,就是我輸入某一個變量,我必須要指定這個變量的地址,所以它是通過這個地址來指向這個變量的,就是你輸入這個變量要存在哪里,它必須去指定這個地址,所以指定這個地址從這個起始地址開始存的時候,那他必定要知道這個類型是什么,因為不同的類型它在內存里邊占的字節(jié)數是不一樣的,所以說,你既然指定了地址,那我必須得知道你占多少個字節(jié),所以必須要知道他是什么類型,所以這個時候它能夠區(qū)分單精度還是雙精度,因為占的字節(jié)數可能是不一樣的;?
在第三個圖中,前邊有3個格式字符,但是我們的后面有兩個輸入項,那中間輸入的數據哪去了呢?因為我們加入了*號,所以他讀入的數據被跳過了;從鍵盤輸入123456(中間是沒有空格的,他怎么沒有把他識別為一個數據呢?因為我們中間使用了位寬的修飾符,所以有了位寬的修飾符它會自動從你輸入的數據里面按照指定的位寬來截取輸入的數據,像%2d我們就從輸入數據里面,截取兩個字符寬度的數據12賦值給a;然后又一個%2d,再截取兩個字符的寬度34,但是34沒有賦值給b,因為前邊有一個*號,他把這個輸入的數據項給跳過去了;然后再有一個%2d,這個56讀入送給b。所以最后輸出的是什么呢?因為中間項被跳過了,輸出結果如上第三個圖)
??如果說中間有了一個逗號,意味著我們要以逗號作為分隔符,來分割這個輸入數據了。總結一下有幾種情況認為輸入數據結束了。?
第一種情況:空格。(輸入一個數據按一個空格)Tab(也可以是輸入一個數據按一下tab鍵)回車(或者輸入一個數據按一個回車再輸入下一個數據)(剛才那個什么也沒有輸入是因為我們指定了位寬)
第二種情況:達到輸出位寬。
第三種情況:遇到非法字符。(本來應該輸入1234,可是我輸入123又輸入一個非法字符a,按回車鍵他真正讀進去的是123,到a就認為這個輸入數據結束了)
?scanf里邊寫什么字符就得原樣輸入什么,但是換行不要輸入。
b里邊的數據沒有正確讀入,所以顯示的就是亂碼。
這個數據從鍵盤讀入內存,他并不是直接讀入內存的,而是中間經過一個輸入緩沖區(qū),先把這個輸入數據存到輸入緩沖區(qū)里邊,然后才從輸入緩沖區(qū)里邊來把他讀到內存里邊;也就是說用戶從鍵盤輸入的時候,他并不是直接來讀用戶的輸入,來賦值給這個變量,存到這個變量指定的地址當中去的,而是把用戶的輸入放到緩沖區(qū)里邊,然后我再從緩沖區(qū)里邊讀取這個數據;也就是說你前一個輸入函數,沒有讀走的這個數據,他可能仍然在緩沖區(qū)里邊,那有可能就被下一個輸入函數給讀取,所以說你要遇到一些中間多輸入的一些數據,這些數據可能會留在緩沖區(qū)里邊,由下一個函數來讀。
單個字符是單引號;
總結
- 上一篇: PCL点云处理算法目录
- 下一篇: CloudComparer点云处理软件