原创 C語言進階46:函數和宏分析
宏除了定義常量,還可以定義代碼塊宏是由預處理器直接替換展開的,編譯器不知道宏的存在函數是由編譯器直接編譯的實體,調用行爲由編譯器決定多次使用宏會導致可執行程序的體積增大函數是跳轉執行的,內存中只有一份函數體存在(也就意味着函數調用有多餘的
原创 40、程序中的內存佈局
先看一張示意圖:不同代碼在可執行程序中的對應關係 程序和進程的不同: 程序是 靜態的 概念,表現形式爲一個可執行文件 進程是 動態的 概念,程序由操作系統加載運行後得到進程 每個程序可以對應多個進程 每個進程只能對應一個程序
原创 C語言進階:24、#pragma使用分析
#pragma用於指示完成一些特定的動作,並且所定義的很多指示字是編譯器特有的。#pragma在不同的編譯器間是不可移植的: ——預處理器將忽略它不認識的#pragma指令 ——不同的編譯器可能以不同的方式解釋一條#pragma指令。一般
原创 C語言進階41:內存操作經典問題《一》——野指針
野指針: 指針變量中的值是非法的內存地址,進而形成野指針 野指針不是NULL指針,是指向不可用內存地址的指針 NULL指針並不危害,很好判斷,也很好調
原创 C語言進階43:函數的意義——模塊化設計和extern
函數的由來: 程序 = 算法 + 數據 C程序 = 數據 + 函數面向過程的程序設計: 面向過程是一種以過程爲中心的編程思想 首先將複雜的問題分解爲一個個容易解決的問題 分解過後的問題可以按照步驟一步步完成 函數是面向過程在C語言
原创 C語言進階:第26課、指針的本質分析
程序中的變量只是一段存儲空間的別名,那麼是不是必須通過這個別名才能訪問這段存儲空間?*號的意義: 在指針聲明時,*號表示所表明的變量爲指針; 在指針使用時,*號表示取指針所指向的內存空間中的值。 *號類似於一把鑰匙,通過這把鑰匙可以打開內
原创 memset()函數
將s所指向的某一塊內存中的每個字節的內容全部設置爲ch指定的ASCII值,塊的大小由第三個參數指定,這個函數通常爲新申請的內存做初始化工作。void *memset(void *s, char ch, unsigned n);”
原创 C語言進階47:遞歸函數分析
遞歸是一種數學上分而治之的思想遞歸需要有邊界條件 當邊界條件不滿足時,遞歸繼續進行 當邊界條件滿足時,遞歸停止 遞歸將大型複雜問題轉化爲與原問題相同遞歸函數: 函數體內部可以調用自己遞歸函數中存在自我調用的函數遞歸函數是遞歸的數學思想在程
原创 C語言進階48: 函數設計原則
函數設計原則: 函數在意義上應該是一個獨立的功能模塊 函數名要在一定程度上反應函數的功能 函數參數名要能夠體現參數的意義 儘量避免在函數中使用全局變量!函數應該是無狀態的,全局變量在函數體中是不受歡迎的。 voi
原创 C語言進階:第27課、數組的本質分析
數組是相同類型的變量的有序集合。int a[5]; // 5個int類型數據,每個元素都是int型數據;a代表數組第一個元素的起始地址。這20個字節空間的名字 爲a,a[0]、a[1]等都是a中的元素,並非元素的名字
原创 C語言進階:25、#和##操作符使用分析
#運算符#運算符用在預處理器期間將宏參數轉換爲字符串#的轉換作用是在預處理器完成的,因此只在宏定義中有效編譯器不知道#的轉換作用用法: #define STRING(x) #x printf("%s\n", STRING(Hell
原创 C語言進階44:函數參數的祕密《上》——參數訪問順序和程序點
函數參數在本質上與局部變量相同,都是在棧上分配空間函數參數的初始值是函數調用時的實參值觀察下面代碼,判斷輸出: int k=1; printf("%d, %d\n", k++, k++); (劃重點)
原创 C語言進階:第30課:C語言中的字符串
字符串的概念:字符串是有序字符的集合;字符串是程序中的基本元素之一;C語言中沒有字符串的概念: C語言中通過特殊的字符數組模擬字符串; C語言中的字符串是以"\0"結尾的字符數組。C語言中,雙引號引用的單個或多個字符是一種特殊的字面量 存
原创 C語言進階:第28課:指針和數組分析(上)
數組的本質: 數組是一段連續的內存空間 數組的空間大小爲sizeof(array_type)*array_size 數組名可以看做指向數組第一個元素的常量指針。 問題: a+1的意義是什麼?結果是什麼? 指針運算的意義是什麼?
原创 C語言進階:23、#error和#line的用法
#error用於生成一個編譯錯誤消息用法: #error message message不需要用雙引號包圍#error編譯指示字用於自定義程序員特有的編譯錯誤消息,類似的,#warning用於生成編譯警告。#error是一種預編譯指