#include<>與#include"" 一、#include<> #include< > 引用的是編譯器的類庫路徑里面的頭文件。 假如你編譯器定義的自帶頭文件引用在 C:\Keil\c51\INC\下面,則 #include<stdio.h> 引用的就是 C:\Keil\c51\INC\stdio.h 這個頭文件,不管你的項目在什么目錄里,C:\Keil\c51\INC\stdio.h 這個路徑就定下來了,一般是引用自帶的一些頭文件,如:stdio.h、conio.h、string.h、stdlib.h 等等。 二、#include"" #include" " 引用的是你程序目錄的相對路徑中的頭文件。 假如你的項目目錄是在 D:\Projects\tmp\ ,則 #include"my.h" 引用的就是D:\Projects\tmp\my.h 這個頭文件,一般是用來引用自己寫的一些頭文件。如果使用#include" " ,它是會先在你項目的當(dāng)前目錄查找是否有對應(yīng)頭文件,如果沒有,它還是會在對應(yīng)的引用目錄里面查找對應(yīng)的頭文件。例如,使用 #include "stdio.h" 如果在你項目目錄里面,沒有 stdio.h 這個頭文件,它還是會定位到C:\Keil\c51\INC\stdio.h 這個頭文件的。
#ifndef和#define區(qū)別 “頭文件中的 #ifndef/#define/#endif 防止該頭文件被重復(fù)引用”。但是是否能理解“被重復(fù)引用”是什么意思?是不能在不同的兩個文件中使用include來包含這個頭文件嗎?如果頭文件被重復(fù)引用了,會產(chǎn)生什么后果?是不是所有的頭文件中都要加入#ifndef/#define/#endif 這些代碼?
其實(shí)“被重復(fù)引用”是指一個頭文件在同一個cpp文件中被include了多次,這種錯誤常常是由于include嵌套造成的。比如:存在a.h文件#include "c.h"而此時b.cpp文件導(dǎo)入了#include "a.h" 和#include"c.h"此時就會造成c.h重復(fù)引用。
頭文件被重復(fù)引用引起的后果:有些頭文件重復(fù)引用只是增加了編譯工作的工作量,不會引起太大的問題,僅僅是編譯效率低一些,但是對于大工程而言編譯效率低下那將是一件多么痛苦的事情。
有些頭文件重復(fù)包含,會引起錯誤,比如在頭文件中定義了全局變量(雖然這種方式不被推薦,但確實(shí)是C規(guī)范允許的)這種會引起重復(fù)定義。
是不是所有的頭文件中都要加入#ifndef/#define/#endif 這些代碼? 答案:不是一定要加,但是不管怎樣,用#ifndexxx #define xxx #endif或者其他方式避免頭文件重復(fù)包含,只有好處沒有壞處。個人覺得培養(yǎng)一個好的編程習(xí)慣是學(xué)習(xí)編程的一個重要分支。 下面給一個#ifndef/#define/#endif的格式: #ifndef A_H意思是"if not definea.h" 如果不存在a.h 接著的語句應(yīng)該#define A_H 就引入a.h 最后一句應(yīng)該寫#endif 否則不需要引入 例子: #ifndefGRAPHICS_H // 防止graphics.h被重復(fù)引用 #defineGRAPHICS_H #include<math.h> // 引用標(biāo)準(zhǔn)庫的頭文件 … #include“header.h” // 引用非標(biāo)準(zhǔn)庫的頭文件 … voidFunction1(…); // 全局函數(shù)聲明 … classBox // 類結(jié)構(gòu)聲明 { … }; #endif
Sbit bit sfr 1.bit和sbit都是C51擴(kuò)展的變量類型。 bit和intchar之類的差不多,只不過char=8位, bit=1位而已。都是變量,編譯器在編譯過程中分配地址。除非你指定,否則這個地址是隨機(jī)的。這個地址是整個可尋址空間,RAM+FLASH+擴(kuò)展空間。bit只有0和1兩種值,意義有點(diǎn)像Windows下VC中的BOOL。 sbit是對應(yīng)可位尋址空間的一個位,可位尋址區(qū):20H~2FH。一旦用了sbi xxx= REGE^6這樣的定義,這個sbit量就確定地址了。sbit大部分是用在寄存器中的,方便對寄存器的某位進(jìn)行操作的。 2.bit位標(biāo)量 bit位標(biāo)量是C51編譯器的一種擴(kuò)充數(shù)據(jù)類型,利用它可定義一個位標(biāo)量,但不能定義位指針,也不能定義位數(shù)組。它的值是一個二進(jìn)制位,不是0就是1,類似一些高級語言中的Boolean類型中的True和False。 3.sfr特殊功能寄存器 sfr也是一種擴(kuò)充數(shù)據(jù)類型,占用一個內(nèi)存單元,值域為0~255。利用它可以訪問51單片機(jī)內(nèi)部的所有特殊功能寄存器。如用sfr P1 = 0x90這一句定P1為P1端口在片內(nèi)的寄存器,在后面的語句中我們用以用P1 = 255(對P1端口的所有引腳置高電平)之類的語句來操作特殊功能寄存器。 sfr P1 = 0x90; //定義P1 I/O 口,其地址90H sfr 關(guān)鍵定后面是一個要定義的名字,可任意選取,但要符合標(biāo)識符的命名規(guī)則,名字最好有一定的含義如P1 口可以用P1 為名,這樣程序會變的好讀好多.等號后面必須是常數(shù),不允許有帶運(yùn)算符的表達(dá)式,而且該常數(shù)必須在特殊功能寄存器的地址范圍之內(nèi)(80H-FFH),具體可查看附錄中的相關(guān)表. sfr 是定義8 位的特殊功能寄存器而sfr16 則是用來定義16 位特殊功能寄存器, 如8052 的T2 定時器,可以定義為: sfr16 T2 = 0xCC; //這里定義8052 定時器2,地址為T2L=CCH,T2H=CDH
有符號型signed和無符號型unsigned的區(qū)別就拿short型來說吧
signed short型的表示范圍是-32768~32767中的整數(shù)
而unsigned short型的表示范圍是0~65535中的整數(shù)
也就是說,signed型能夠表示負(fù)數(shù),而unsigned則不能,但signed表示的最大數(shù)總要比unsigned小,其原因是因為在內(nèi)存中signed需要用1位(short型共有16位)來存儲正負(fù)號,unsigned型沒有正負(fù)號,所以這1位也就節(jié)省了下來和其它位一起表示整數(shù)了。
int型、long型同理
如果要運(yùn)算的數(shù)存在負(fù)數(shù)的可能,那么一定要用signed。如果不存在負(fù)數(shù),且要求存儲的數(shù)據(jù)范圍盡可能大,則一般用unsigned型。
如果聲明變量時不指明signed還是unsigned,則默認(rèn)為signed
char是字符變量的說明符 字符變量的取值是字符常量,即單個字符。字符變量的類型說明符是char。字符變量類型說明的格式和書寫規(guī)則都與整型變量相同。 unsignedchar code table[ ]={ }; 定義一個無符號字符型一維數(shù)組,table是數(shù)組名table[],中的[],省掉了一個參數(shù),如果有參數(shù),參數(shù)就表示些數(shù)組包含的個數(shù),{}里的值就是數(shù)組包含的值。上面的代碼可以寫成 unsignedchar code table[16]={0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71}; unsignedchar TempData[8]; unsignedchar是無符號字節(jié)型,char類型變量的大小通常為1個字節(jié)(1字節(jié)=8個位),且屬于整型。整型的每一種都有無符號(unsigned)和有符號(signed)兩種類型(float和double總是帶符號的),在默認(rèn)情況下聲明的整型變量都是有符號的類型(char有點(diǎn)特別),如果需聲明無符號類型的話就需要在類型前加上unsigned。無符號版本和有符號版本的區(qū)別就是無符號類型能保存2倍于有符號類型的數(shù)據(jù),比如16位系統(tǒng)中一個int能存儲的數(shù)據(jù)的范圍為-32768~32767,而unsigned能存儲的數(shù)據(jù)范圍則是0~65535。
VOID 表示空類型,它跟int,float是同地位的,一般用在沒有返回值的函數(shù)中,比如你寫void main (),主函數(shù)完了不用寫return 語句,但是如果是int main ()或者是main (),你不寫return 語句它就會有warning void是C語言中的一個關(guān)鍵字,字面意思是“無類型”,常用在程序編寫中對定義函數(shù)的參數(shù)類型、返回值、函數(shù)中指針類型進(jìn)行聲明,有注釋和限制程序的作用。void *可以指向任何類型的數(shù)據(jù),在C語言中,凡不加返回值類型限定的函數(shù),就會被編譯器作為返回整型值處理。 void的字面意思是“無類型”,void *則為“無類型指針”,void *可以指向任何類型的數(shù)據(jù)。 void幾乎只有“注釋”和限制程序的作用,定義一個void變量沒有意義。
|