C程序设计语言——基础概念
C語言從入門到精通
每天進步一點點,日積月累。
紙上得來終覺淺,絕知此事要躬行。
C 語言概述
為什么學習C語言
C語言的起源和發展
結構化語言:使得它的數據和操作是分離的
面向對象語言
速度:C>C++>Java
C語言的特點
優點:代碼量小、速度快、功能強大
windows C內核 C++外包
Unix C
linux C
缺點:危險性高、開發周期長、可移植性不強
C語言的應用領域
系統軟件開發
應用軟件開發
模塊化程序設計思想
在設計較復雜的程序時,一般采用自頂向下的方法,將問題劃分為幾個部分,各個部分再進行細化,直到分解為較好解決問題為止。
模塊化設計,簡單地說就是程序的編寫不是一開始就逐條錄入計算機語句和指令,而是首先用主程序、子程序、子過程等框架把軟件的主要結構和流程描述出來,并定義和調試好各個框架之間的輸入、輸出鏈接關系逐步求精的結果是得到一系列以功能塊為單位的算法描述。以功能塊為單位進行程序設計,實現其求解算法的方法稱為模塊化。
模塊化的目的是為了降低程序復雜度,使程序設計、調試和維護等操作簡單化。
利用函數,不僅可以實現程序的模塊化,使得程序設計更加簡單和直觀,從而提高了程序的易讀性和可維護性,而且還可以把程序中經常用到的一些計算或操作編寫成通用函數,以供隨時調用
舉例:
C語言編程預備知識
CPU、內存條、硬盤、顯卡、主板、顯示器之間的關系
某雙擊硬盤上存放的文件(視頻,音頻),單擊后操作系統將硬盤上數據調入內存條中,CPU去處理內存條中數據,圖像的話通過顯卡在顯示器顯示。
程序如何運行起來
文本編譯軟件上寫完程序后,點擊編譯(Compiler)、鏈接(Linker)之后Visual C++生成 .exe可執行文件,再點擊運行(Built)之后,Visual C++請求OS去調用CPU執行 .exe文件。
編譯:由編譯程序對用戶源程序進行編譯,形成若干個目標模塊(Object Module)。
鏈接:由鏈接程序將編譯后形成的一組目標模塊以及它們所需要的庫函數鏈接在一起,形成一個完整的裝入模塊(Load Module)。
裝入:由裝入程序將裝入模塊裝入內存。
編譯預處理
-
定義
#開頭的是編譯預處理指令,它們不是C語言成分,但是C語言離不開它們 -
宏定義
#define 宏名 替換文本#define PI 3.14159在C語言編譯器開始編譯前,編譯預處理程序會把程序中的名字替換成值
不帶參數的宏定義帶參數的宏定義
#define 宏名 (參數表) 字符串#define RADTODEG ((x)*57.29)
標識符
命名規則:只能由字母與數字、下劃線組成第一個字符必須是字母或下劃線區分字母大小寫不能是C語言關鍵字分類:關鍵字預定義標識符用戶標識符什么是數據類型
什么是變量
變量的本質:是內存中一段存儲空間,不同類型的變量其存儲單元大小不同
定義:值可以改變的量
存儲單元里存放的是該變量的值
變量要有變量名,在使用前必須先定義
變量的數據類型:
字符型數據與整型數據之間可以通用,一個字符能用字符的形式輸出,也能用整數的形式輸出(字符的本質上是代表一個十進制整數)
變量的運算:
字符數據進行算術運算,相當于對他們的ASCII碼進行運算 /* 字母轉換來理解字符變量的運算過程 以下為小寫字符轉換為大寫字符 */#include <stdio.h>int main(void) {char ch;scanf("%c", &ch);//方式一 printf("%c\n", ch-32);//由于字符本質就是使用ASCII碼的十進制整數進行存儲,所以可以直接運算//方式二printf("%c\n", ch-'\x20');//十六進制的'\x20'表示十進制32所代表的字符 //方式三printf("%c\n", ch-' ');//空格字符' '表示十進制的32 return 0; }總結:
C語言并無char類型,就是用Int表示char的!char占一個字節,在C語言所有類型中最小。
在C語言中,實際上字符型數據在內存中是以二進制形式存放的,并不是真正的把一個字符存進內存里。在對字符型數據進行相加減運算的時候,系統會首先會將char型數據以隱形的方式轉化成int型數據再進行相加減運算的。因此,由字符型數據在內存的存儲方式來看,字符型數據是可以進行數值運算的,對字符型數據做數字運算實際上就是對字符本身對應的ASCII碼進行相應的數值運算。
“ 整型”和“字符型”可以互相轉換:
(char)整型變量=字符型變量(int)字符型變量=整型變量變量為什么必須初始化(賦值)
軟件運行期間,軟件所占的內存空間不再分配給其他軟件,當軟件運行完畢后,OS將回收內存空間(OS并不清空該內存空間遺留下的數據)
如何定義變量
數據類型 變量名=要賦的值
(int price = 10;)
進制
什么叫進制
十進制就是逢十進一:0 1 2 3 4 5 6 7 8 9 10 11二進制就是逢二進一:0 1 10 11 100 101 110 111十六進制就是逢十六進一:0 1 2 3 4 5 6 7 8 9 A B C D E F進制轉換的預備知識
把r進制轉換為十進制
把十進制轉換成r進制
1. 把十進制轉換為二進制
2. 把十進制轉換為八進制
3. 把十進制轉換為十六進制
十進制轉r進制方法:除r取余,直至商為0,余數倒敘排列
二進制與十六進制轉換
一個十六進制位必須用4個二進制位表示 一個八進制為必須用是三個二進制位表示不同進制所代表的的數值之間的關系
十進制的3981轉換為十六進制是F8D十進制的3981和十六進制的F8D所代表的本質上都是同一個數C語言規定八進制前加:0
C語言規定十六進制前加:0X
二進制的101和十進制的5,本質上是一樣的,只是外部形式不同。
常用計數制對照表
同一個值不同的進制表示形式不同
什么是常量
在程序運行中,其值不能被改變的量。
常量在C語言中如何表示
在字符集中,有一類字符具有這樣的特性:當從鍵盤上輸入這個字符時,顯示器上 就可以顯示這個字符,即輸入什么就顯示什么。這類字符稱為可顯示字符,如a、b、c、$、+和空格符等都是可顯示字符。
另一類字符卻沒有這種特性。它們或者在鍵盤上找不到對應的一個鍵(當然可以用特殊方式輸入),或者當按鍵以后不能顯示鍵面上的字符。其實,這類字符是為控制作用而設計的,故稱為控制字符。 在C語言中,構成字符常量的控制字符必須用轉義字符表示。
通常使用轉義字符表示ASCII碼字符集中不可打印的控制字符和特定功能的字符,下表是常用的轉義字符及其含義。
| \a | 響鈴(BEL) | 007 |
| \b | 退格(BS) ,將當前位置移到前一列 | 008 |
| \f | 換頁(FF),將當前位置移到下頁開頭 | 012 |
| \n | 換行(LF) ,將當前位置移到下一行開頭 | 010 |
| \r | 回車(CR) ,將當前位置移到本行開頭 | 013 |
| \t | 水平制表(HT) (跳到下一個TAB位置) | 009 |
| \v | 垂直制表(VT) | 011 |
| \|代表一個反斜線字符’ \ ’ | 092 | |
| \’ | 代表一個單引號(撇號)字符 | 039 |
| \" | 代表一個雙引號字符 | 034 |
| \0 | 空字符(NULL) | 000 |
| \ddd | 1到3位八進制數所代表的任意字符 | 3位八進制 |
| \xhh | 1到2位十六進制所代表的任意字符 | 2位十六進制 |
由上可知,使用八進制轉義字符和十六進制轉義字符,不僅可以表示控制字符,而且也可以表示可顯示字符。但由于不同的計算機系統上采用的字符集可能不同,因此,為了能使所編寫的程序可以方便地移植到其他的計算機系統上運行,程序中應少用這種形式的轉義字符。
常量以什么樣的二進制代碼存儲在計算機中
整數以補碼的形式轉化為二進制代碼存儲在計算機中的。
實數以IEEE754標準轉化為二進制代碼存儲在計算機中的。
字符的本質實際也是與整數的存儲方式相同。
代碼規范化
推薦閱讀《高質量程序設計指南C/C++編修》
讓別人和自己更容易可讀和理解
什么是字節
字節就是存儲數據的單位,并且是硬件所能訪問的最小單位。
1字節(Byte) = 8位(Bit)
什么是ASCII碼
ASCII不是一個值,而是一種規定。
ASCII規定了不同的字符是使用哪一種整數值去表示。
GB2312和UTF-8規定不同字母用什么數字表示。
運算符和表達式
-
算術運算符:+,-,*,/,%
-
除法/的運算結果和運算對象的數據類型有關
兩數都是int,則商是int除數和被除數只要有一個/兩個是浮點數,則商是浮點型 -
取余%的運算對象:兩個操作數必須是整數(int類型),結果是整除后的余數
其余數的符號與被除數相同例如:13%-3==1;-13%3==-1;3%5==3;-3%5==-3;1%25=1當被余數小于余數時,結果就是被余數舉例:要得到一個三位數456的個位、十位、百位個位數:456%10=6十位數:456/10%10=5百位數:456/10=4 -
關系運算符:>,<,>=,<=,!=,==
-
位運算符:>>,<<,~,&,|,^
-
&——按位與
1&1 = 11&0 = 00&1 = 00&0 = 0 #include <stdio.h>int main(void) {int i = 5;int j = 7;int k;k = i&j; //表示5的二進制0101與7的二進制0111相與,結果是0101還是5printf("%d\n", k);k = i&&j;printf("%d\n", k); //k的值只能是1或0,因為&&是邏輯運算符 return 0; } //結果為:51 -------------------------------- -
|——按位或
1|0 = 11|1 = 10|1 = 10|0 = 0例如:5|2等價于00000101|00000010,結果為00000111 #include <stdio.h>int main(void) {int i = 3;int j = 5;int k;k = i | j;printf("%d\n", k);return 0;//結果: 7 -------------------------------- } -
~——按位取反
~i就是把i變量所有的二進制位取反 -
^——按位異或
規則是參與運算的兩個運算符中相對應的二進制位上,若數相同,則該位的結果為0,否則為1相同位0,不同位11^0 = 10^1 = 11^1 = 00^0 = 1例如:s=32,s^=32,printf("%d", s), 相同為假不同為真,結果是03^2等價于00000011^00000010,結果為00000001,十進制是1 -
<<——按位左移
i<<1表示把i的所有二進制位左移一位,右邊補0.左移n位相當于乘以2的n次方例:i = i * 8i = i << 3 速度快 -
>>——按位右移
i>>3表示把i的所有二進制位右移3,左邊一般都是0有移n位表示除以2的n次方(不能溢出導致數據丟失)位運算符的現實意義:通過位運算符我們可以對數據的操作精確到每一位
-
邏輯運算符:!,||,&&
-
C語言對真假處理
非0是真 真表示10是假 假是0表示例如:(!a == 0)<==> ((!a) == 0)因為!的優先級高于== 它表示是a不等于0時為真(a == !0)表示的是a等于1的時候為真 -
C語言真假判斷
&&左邊的表達式為假,右邊的表達式肯定不執行||左邊的表達式為真,右邊的表達式肯定不執行 -
&&邏輯與也叫并且
-
邏輯運算符的結果只能是0或1
-
條件運算符:?:
格式:A ? B : C 等價于 if(A) //當表達式A為真,執行表達式BB;else //當表達式A為假,執行表達式CC; -
指針運算符:&,*
-
賦值運算符:=
作用:將一個數值賦值給一個變量或將一個變量的值賦給另一個變量。
賦值表達式一般形式:變量名=表達式/變量/值
注:左邊不能是表達式,右邊可以是賦值表達式a+b=c 錯誤的a=b=7+1 正確的a=7+1=b 錯誤的復合賦值表達式:+=、-=、*=、/=、%=
例子:t *= sum +12 <==> t = t * (sum + 12)x-=x+x <==> x=x-(x+x) +的優先級高于-=5=4+1錯誤,常量5不能被賦值舉例:已有變量a=9,計算表達式a+=a-=a+a的值1. 先計算a+a=182. 計算a-=18(此時a任然是9) a=a-18,a變為-93. 計算a+=-9(此時a是-9) a=a+-9 ,a變為-18 -
逗號運算符:,
逗號表達式:用逗號運算符將幾個表達式連接起來格式:A;B;C;D;……功能:從左到右依次執行,最終表達式的值是最后一項的值例如:j=2;i=(j++,++j,j+2,j-3) 最終i=3(i=3,i++,++i,i+5)從左向右計算,i++之后i為4,++i之后i為5,i+5之后值為10,所以表達式的值為10,i為5 -
字節運算符:sizeof
sizeof(類型):是靜態得到字節數,不會影響下面語句 -
強制運算符:(類型名)(表達式)
利用強制類型轉換符將一個表達式轉換為前面所執行的數據類型一般形式:(類型名)(表達式)例子:(float)(5) 最終值為5.000000 -
初等運算符:圓括號(),下標運算符[ ],結構體成員運算符->
-
單目、雙目、三目運算符
單目就是這個運算符只對一個變量進行操作代表符號:!(邏輯非) ,~(按位取反),++(自增),--(自減)雙目就是這個運算符對兩個變量進行操作三目就是這個運算符對三個變量進行操作代表符號: ?: (條件運算符) -
自增、自減運算符
作用:自增運算符++,使運算變量的值增1,自減運算符--,使運算變量值減一均是單目運算符分類:前自增++i,后自增i++相同點:最終都使i的值加一不同點:前自增整體表達式的值是i加1之后的值;后自增整體表達式的值是i加1之前的值注意:for循環條件語句中出現++i或者i++都是一樣的,沒有區別,因為條件語句for(i++; ; )中是執行完第一個條件之后,再執行第二個條件語句與賦值運算符=不同,例子:
int a = 10;printf(a++) = 10;printf(a) = 11;printf(++a) = 12;printf(a) = 12;visit(*p++); 第一次先輸出*p,下一次才輸出*p+1compare(*p++, e)是先比較*p與e的值,第二次才是用*p+1和e的值進行比較k++是先取K的值再將k的值自增1 為什么會出現自增:1. 代碼更精煉2. 自增的速度更快 i++>i=i+1學習自增前要明白的幾個問題1. 我們編程是應該盡量屏蔽掉前自增和后自增的區別2. i++和++i單獨成一個語句,不要把它作為一個完整復合語句的一部分使用。
運算符的優先級和結合性
優先級:初等>單目>算術>關系>邏輯>條件>賦值>逗號
結合性:左結合性->單目,條件,賦值,擴展;其余右結合性
圖示運算符優先級和結合性
最高級:出現同級別運算符時的結合方向是從左往右
第二級:這一級都是單目運算符號,這一級的結合方向是從右向左。
出現 * p++,這時 * 和++同級別,先算右邊,再左邊。所以 * p++等價于 * (p++)
第三級:這一級都是算術運算符,結合順序和數學學習中一致的,先乘除取余數,后加減。
第四級:這是左移、右移運算符,位運算時可能需要用到。
第六級:這三個符號也是位運算符號,其中內優先級,&>^>|。
第七級:邏輯與&&優先級大于邏輯或||。
第八級:也稱為條件運算符號,是C語言中唯一的一個三目運算符,結合順序是從右往左。
第九級:這些運算符也叫做賦值運算符,除此之外,>>=、<<=、&=、^=、|=這些賦值運算符也在這一級別內,結合順序是從右往左。
最低級:逗號運算符也稱為順序求值運算符,在C語言中,運算級別最低。
表達式
C語言一些瑣碎的知識
浮點數的存儲所帶來的的問題
float和double都不能保證可以精確的存儲一個小數。
為什么循環中更新的變量不能定義為浮點型呢
因為浮點型不一定能準確存儲。二進制全部為0的含義——0000000…00000的含義
-
表示數值零
-
表示字符串結束標記 ‘\0’
-
空指針NULL
NULL本質也是0,而這個零不代表數字零,而表示的是內存單元的編號為零(表示0地址,即編號為零)我們計算機規定了,以零為編號的存儲單元的內容不可讀,不可寫 -
0地址
在現代OS中,多進程中,OS給程序虛擬地址空間,所有程序在運行時都以為自己從0開始的一片連續空間(32位機器,頂是4G)一般0地址不能碰的,在這種情況下,用0地址表示特殊事情1. 返回指針無效2. 用NULL表示0地址
什么叫分配內存,什么叫釋放內存
分配內存:
OS把某一塊內存空間的使用權限分配給該程序釋放內存:
OS把分配給該程序的內存空間的使用權限收回,該程序不能夠再使用這一塊內存空間注:釋放內存不是把該內存的內容清零變量為什么必須得初始化
不初始化,則變量通常就是垃圾值
總結
以上是生活随笔為你收集整理的C程序设计语言——基础概念的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 用友NC CLOUD 工具
- 下一篇: 数学分析练习题答案一(自己做的)