當前位置:首頁 » 編程軟體 » cc編程規范

cc編程規范

發布時間: 2022-09-25 19:28:32

c語言編寫一個程序後,為什麼編譯是是文件不存在,要如何調節

可能是你的文件夾地址設置不正確,不知道你用了那個版本的C,如果是TC,可以這樣去檢查一下(設TC目錄是C:\TC):
運行TC,進入Options/Directories,把其中的Include Directories設置為C:\TC\INCLUDE 。

❷ 如何學好一門編程語言

學好一門編程語言是十分不容易的,但是如果學會了,它的實用性是很強的,下面我為大家整理了學好一門編程語言的辦法,大家可以參考借鑒。


如何學好一門編程語言?

一、多總結

多總結才能加深理解、增強記憶。舉例,Go 中有 slice、map、channal 類型,它們都可以用 make 生成實例,但 slice 和 map 還可以用以下形式初始化,也是編程規范中建議的初始化方式:

colors := map[string]string{}

slice := []int{}

但注意了,channal 則沒有這樣的語法:msg := chan string{}

上面兩句是生成實例,表示空集合,但下面兩句則表示實例不存在,值為 nil

var colors map[string]string

var slice []int

另外,結構體指針 slice 還可以象下面這樣初始化,結構體實例不用明確地指定類型(使用了類型推導)、不用明確地取地址運算(&)。

type Proct struct {

name string

price float64

}

procts := []*Proct{{"Spanner", 3.99}, {"Wrench", 2.49}, {"Screwdriver", 1.99}}

看到沒有,如果不經常總結,這一圈學下來會把你整的稀里糊塗的。

二、多比較

學一門新語言一定要與你之前已經熟悉的語言經常作比較,找出它們的相同與不同,這樣才能加深記憶和理解,否則學完之後腦子里會一片混亂,搞不清誰是誰非了。

就拿數組來說吧,在 Java、Scala、Go 中定義、實例化、賦值是不一樣的。

//Java

int[] arr;//定義數組,不可以指定數組長度

arr = new int[5];//創建數組對象(實例化),指定數組長度

arr[1] = 8;//賦值

//Scala

val arr = new Array[Int](5) //數組在Scala里用的是泛型類,構造函數參數指定數組大小

arr(1) = 8 //賦值,注意用的是括弧

//Go

arr := [5]int{} //創建數組,初始化5個元素都為0,注意如果不指定數組長度,則是另外一種類型Slice

arr[1] = 8 //賦值

再比如 Map 在 Scala 與 Go 語言里定義、初始化、訪問也是不同的,作了以下比較後印象會非常深刻,把它們記下來,這樣以後使用就不會搞混了。

//Scala

val capital = Map("France" -> "Paris", "Japan" -> "Tokyo")

println(capital.get("France"))

//Go

capital := map[string]string{"France": "Paris", "Japan": "Tokyo"}

fmt.Println(capital["France"])

Go 同時給多個變數賦值在 Scala 里可以用模式匹配做到,如下:

//Scala(使用樣本類的模式匹配)

case class Tao(name: String, age: Int);

val Tao(myName, myAge) = Tao("taozs", 18);

println(myName)

println(myAge)

//Go

myName, myAge := "taozs", 18

fmt.Println(myName)

fmt.Println(myAge)

//Scala(使用元組的模式匹配)

val (myNumber, myString) = (123, "abe")

println(myNumber)

println(myString)

//Go

myNumber, myString := 123, "abe"

fmt.Println(myNumber)

fmt.Println(myString)

以下是 Scala 和 Go 定義和實現函數的區別:

//Scala

val increase: Int => Int = (x: Int) => x + 1

println(increase(8))

//Go

var increase func(int) int = func(x int) int { return x + 1 }

fmt.Println(increase(8))

除了在 Scala 和 Go 里都可以類型推導外,在 Scala 里還可以這樣定義函數:

//Scala

val increase = (_: Int) + 1

為方便自己將來隨時查閱,可以建立下面這樣的對比表格,描述不一定要求規范,自己能看懂就行。

三、轉變思維方式,

學會用這門語言去思考

學會用語言去思考是關鍵。如果你以前是學 C 的,轉學 Java,你一定要改變以前面向過程的思維,學會用面向對象的思維去分析問題;以前學 Java 的,轉學 Scala 則要學會用函數式的編程思維解決問題。

舉一個函數式編程的例子,以下是 Java 語言常用的 for 循環,循環變數從 1 到 10 執行 10 次循環體:

// 命令式編程

for (int i = 1; i < 10; i++) {

// 此處是循環體做10次

}

這被稱為命令式編程 (Imperative Programming),但學了 Scala 的函數式編程 (Functional Programming) 後,解決同樣的問題,我們可以換一種思維:構建 1 到 10 的列表序列,針對列表中的`每個元素分別執行函數,如下:

//函數式編程

val autoList = (1 to 10).map(i => /*此處是函數體,針對1到10的每一個分別調用 1次*/)

已經習慣了 Java 編程的,對 Scala 的函數式編程、樣本類、模式匹配、不可變對象、隱式轉換等需要一個逐步適應的過程,要漸漸學會用它們思考和解決問題。

再舉個 Scala 與 Go 思維方式不同的例子,要實現對一個字元串里的每個字元加 1 的操作,Scala 里可以這樣:

"abc".map(cc => cc + 1)

"abc"是一個字元串對象,調用它的方法 map,這是純面向對象的思維,但在 Go 里就要轉變為面向過程的思維:

name := "abc"

second := strings.Map(func(x rune) rune {

return x + 1

}, name)

注意,這里的 strings 是包 (package),調用它的公共函數 Map,被人操作的對象 name 字元串作為函數參數傳入。Go 提供的函數 len、cap、append、 等其實都是面向過程的,雖然 Go 也提供有面向對象的支持,已經習慣了面向對象編程的,剛開始學 Go 語言需要特別留意這一點。

四、多看開源代碼

學一門語言就是學一種思維方式,如今 GitHub 上可下載的開源代碼海量級,通過看別人的代碼,學習別人是如何解決問題的,養成用該語言思考的習慣,另外還能學習到一些非常有用的技巧,比如我在看一個 Go 語言性能測試框架代碼時看到有以下寫法:

func main() {

defer profile.Start().Stop()

...

}

這個意思是指剛進入程序時執行 Start( ) 函數,程序退出前調用 Stop( ) 函數,非常好的技巧啊!可以用於需要在程序執行前和程序完成後分別執行一段邏輯的場景。再看 Start( ) 函數是怎麼實現的:

func Start(options ...func(*Profile)) interface {

Stop()

} {

...

return &prof

}

該函數返回了一個實現了含有 Stop( ) 函數介面的對象,如此才能在調用 Start 調用後連調 Stop。

五、優先學會使用代碼分析工具

代碼分析的工具包括靜態檢查、測試、測試覆蓋率分析、性能分析(內存、CPU)、調試工具等,工具的價值在於它可以有效幫我們發現代碼問題,這在我們剛開始學一門編程語言時意義尤其重大。

例如,以下這句 Java 賦值語句估計沒有哪本教科書會告訴你有性能問題:

String sb = new String(「Hello World」);

以下這段 Java 代碼你也不一定能意識到有多線程問題:

synchronized public void send(authuserPacket pkt, Thread t, String flowNo) throws IOException

{

logger.info("start");

//連接不可用,直接拋出異常,等待接收線程連接伺服器成功

if (!this.avaliable)

{

try

{

//如果連接不可用,則等待2S,然後重新檢測

Thread.sleep(2000);

}

... ...

如果我們及時用 FindBugs 工具檢查就會發現上面這些問題,進而你會去分析研究為什麼,如此,你對這門語言的了解也會越來越多。

另外,Go 語言自帶的 vet/test/cover/pprof/trace 都是非常有用的工具,一邊學一邊使用這些工具分析代碼,能加深對語言的理解。

六、多練習、多實踐

就象學自然語言一樣,如果只知道語法不去練是沒有任何效果的,只有反復地練習,慢慢才能變成自己的一項技能。書本上的例子代碼最好能從頭到尾親自敲一遍,多運行、多嘗試,另外再找一些題目來練習,如能有機會參與項目開發則更好啦,勤動手、勤實踐是最好的學習方法。

其它的方法還有:

做好筆記,把學習中遇到的關鍵點和自己的思考記下來,便於後面復習和對比;

復習,學習一定要重復、重復、再重復;

學習貴在堅持,每天學一點(比如堅持每天學 1 小時),日積月累。

❸ 怎麼用visual c++6.0寫.cc程序本人在自學primer c++..

首先打開VC6,然後點新建文本文件,第三行第一個圖標就是了!!然後在代碼區輸入代碼,然後按F5,提示創建工程點是,再把彈出的文件名改成以cpp為後綴的,點保存,一路點是,就能運行了,希望能幫到你

❹ c語言未經處理的異常,求大佬指點

您好,很高興回答您的問題。

您的這個題目,系統已經很明顯告訴您了錯誤的原因。因為您定義的x為字元型數據,那麼它對應的輸入輸出格式符為%c,但是您在輸入語句中寫的是%s,是字元串格式,不符合字元型單個變數的輸入輸出。根據題目意思,應該是要輸入字元串,那麼定義的時候就要寫成charx[2],因為存放的是性別中文字,所以數組長度定義為2就可以了。您再試試哦。

❺ c語言,c++,c#,vc++有什麼區別

如上所說,vc和vc++是一回事,都是指微軟的visual
c++。vc是c的發展,c是過程語言,vc是面向對象的。
c#是微軟的另一個語言,微軟為了擺脫c語言的框架和一些不足另外設計的完全面向對象語言。
從某種意義上說vc是介於c語言和c#之間的半對象半過程語言。
現在在微軟的.net平台里,語言已經不是界限。某種意義上說,Java是跨平台語言,.net是跨語言平台。

❻ USB type C中CC端的工作原理流程是怎樣的

USB Type-C介面支持多種OEM產品定製模式,以擴展設備功能。信號的重新分配是通過CC通道上的協商實現。介面可進入兩種模式,外設模式和替代模式。要進入外設模式,CC通道上將進行簡單的邏輯檢測以確定需要哪種外設模式。

要進入替代模式,CC通道上將使用雙相符號編碼(Biphase Mark Code,BMC)進行雙向通信以正確地設置鏈路。在這個協商過程中,兩端的設備均需要在進行任何改變之前對信號的重新分配協商一致。所有的USB Type-C介面均被要求在非替代模式或非外設模式下能夠作為兼容USB的介面使用。



(6)cc編程規范擴展閱讀

USB為一個外部匯流排標准,用於規范電腦與外部設備的連接和通訊。USB介面即插即用和熱插拔功能。USB介面可連接127種外設,如滑鼠和鍵盤等。USB是在1994年底由英特爾等多家公司聯合在1996年推出後,已成功替代串口和並口,已成為當今電腦與大量智能設備的必配介面。

USB版本經歷了多年的發展,到如今已經發展為3.0版本。對於大多數工程師來說,開發USB2.0 介面產品主要障礙在於:要面對復雜的USB2.0協議、自己編寫USB設備的驅動程序、熟悉單片機的編程。這不僅要求有相當的VC編程經驗、還能夠編寫USB介面的硬體(固件)程序。

所以大多數人放棄了自己開發USB產品。為了將復雜的問題簡單化,西安達泰電子特別設計了USB2.0協議轉換模塊。USB20D模塊可以被看作是一個USB2.0協議的轉換器,將電腦的USB2.0介面轉換為一個透明的並行匯流排,就象單片機匯流排一樣。

❼ CC程序員實用大全怎麼樣

譯者序 第一章 C語言入門 1 編程簡介 2 創建ASCII碼源文件 3 編譯C程序 4 語法錯誤 5 典型的C程序結構 6 往程序里添加語句 7 在新的一行上顯示輸出結果 8 C語言區分大小寫字母 9 邏輯錯誤BUG 10 程序開發過程 11 文件類型 12 進一步了解連接器 13 頭文件 14 幫助編譯器查找頭文件 15 加速編譯 16 注釋程序 17 提高程序的可閱讀性 18 注意編譯器警告信息 19 控制編譯器警告 20 用注釋屏蔽警告 21 名字的重要性 22 分號的作用 23 變數 24 給變數賦值 25 變數類型 26 定義同一類型的多個變數 27 定義變數時加上注釋 28 給變數賦初值 29 在定義時初始化多個變數 30 使用有意義的變數名 31 C關鍵字 32 整型變數 33 字元型變數 34 浮點型變數 35 雙精度型變數 36 給浮點型變數賦值 37 類型標識符 38 無符號類型標識符 39 LONG長類型標識符 40 聯合使用無符號和長類型標識符 41 使用大數值 42 寄存器類型標識符 43 短SHORT類型標識符 44 從類型申明中去掉INT 45 有符號類型示識符 46 多賦值運算符 47 把變數的值賦給另一種類型的變數 48 創建用戶自己的類型 49 賦給十六進制或八進制值 50 溢出 51 精確度 52 賦值為引號或其他字元 53 PRINTF入門 54 使用PRINTF顯示整型數值 55 列印八進制或十六進制整數 56 用PRINTF顯示無符號整型數值 57 用PRINTF顯示長整型數值 58 用PRINTF顯示浮點型數值 59 用PRINTF顯示字元型數值 60 用指數格式顯示浮點數 61 顯示浮點數 62 用PRINTF顯示字元串 63 用PRINTF顯示指針地址 64 在數值前添加正號和負號 65 用PRINTF格式化整數值 66 0填充整數輸出 67 在八進制和十六進制數前顯示前綴 68 用PRINTF格式化浮點數 69 格式化指數輸出 70 左對齊PRINTF的輸出 71 聯合使用格式符 72 字元串的換行 73 顯示NEAR和FAR字元 74 使用PRINTF的轉義字元 75 判斷PRINTF已顯示的字元數目 76 使用PRINTF的返回值 77 使用ANSI設備驅動器 78 用ANSI驅動器清除屏幕顯示 79 用ANSI驅動器顯示屏幕顏色 80 用ANSI驅動器定位游標 81 在C中作基本的數學運算 82 模運算(取余運算) 83 運算符的優先順序和結合性 84 強制操作符運算順序 85 C的自增運算符 86 C的自減運算符 87 按位或運算 88 按位與運算 89 按位異或運算 90 「取反」運算 91 對變數的值進行運算 92 C的條件運算符 93 C的長度SIZEOF運算符 94 移位運算 95 位循環運算 96 條件運算符 97 循環控制 98 C如何表示真TRUE和假FALSE 99 用IF判斷條件 100 簡單語句和復雜語句 101 判斷是否相等 102 關系判斷 103 用邏輯與判斷兩個條件 104 用邏輯或判斷兩個條件 105 邏輯非運算 106 將條件結果賦值給變數 107 在復合語句中定義變數 108 使用縮進來提高程序的可讀性 109 使用擴展CTRL+BREAK檢查 110 判斷浮點數 111 永遠循環下去 112 賦值判斷 113 IF-IF-ELSE語句 114 按規定次數執行語句 115 FOR語句的有些部分是可選擇的 116 在FOR語句中賦值 117 控制FOR循環的增值 118 在FOR循環中使用字元型和浮點型數值 119 空循環 120 無窮循環 121 在FOR循環中使用逗號運算符 122 不要在FOR循環中改變控制變數的值 123 用WHILE循環重復執行一條或多條語句 124 WHILE循環的組成部分 125 使用DO重復執行一條或多條語句 126 C的CONTINUE語句 127 使用C的BREAK語句來結束循環 128 GOTO語句分支 129 判斷多個條件 130 在SWITCH中使用BREAK 131 使用SWITCH語句的DEFAULT CASE 第二章 宏與常量 132 在程序中定義常量 133 宏與常量擴展 134 給常量和宏命名 135 使用-FILE-預處理器常量 136 使用-LINE-預處理器常量 137 改變預處理器的行計數 138 生成無條件預處理器錯誤 139 其他預處理器常量 140 記錄預處理器的日期和時間 141 判斷是否進行ANSIC編譯 142 判斷是C++還是C 143 取消宏或常量 144 比較宏與函數 145 編譯器PRAGMAS 146 預定義值和宏 147 創建用戶自己的頭文件 148 使用#INCLUDE<FILENAME.H>或#INCLUDE「FILENAME.H」 149 判斷符號是否被定義 150 進行IF-ELSE預處理 151 更強大的預處理器條件判斷 152 實現IF-ELSE和ELSE-IF預處理 153 定義需要多行的宏和常量 154 創建自定義宏 155 在宏定義中不要放置分號 156 創建MIN和MAX宏 157 創建SQUARE CUBE宏 158 注意宏定義中的空格 159 如何使用括弧 160 宏是沒有類型的 第三章 字元串 161 C字元串的形象化 162 編譯器是如何表示字元串的 163 C是如何存儲字元串的 164 『A』是如何區別於『A』的 165 在字元串常量內表示引號 166 判斷字元串的長度 167 使用STRLEN函數 168 將一個字元串的字元復制到另一個字元串中 169 將一個串的內容追加到另一個串上 170 給字元串追加N個字元 171 把一個字元串轉移到另一個字元串 172 不要越過字元串的界限 173 判斷兩個字元串是否相同 174 比較字元串時忽略大小寫 175 將字元串轉換成大寫或小寫 176 獲取字元串中第一次出現的某個字元 177 返回索引到串的首次出現 178 搜索字元在字元串中的末次出現 179 返回指向字元中末次出現的索引 180 使用FAR字元串 181 為FAR字元串編寫字元串函數 182 計算字元串的內容反轉 183 將字元串的內容反轉 184 將某特定字元賦給整個字元串 185 比較兩個字元串 186 比較兩個字元中的前N個字元 187 不考慮大小寫比較字元串 188 將字元串轉換成數字 189 復制字元串的內容 190 從給定字元序列中查找字元的首次出現 191 在字元串中查找子字元串 192 計運算元字元串出現的次數 193 給子字元串獲取索引 194 獲取子字元串的最右端出現 195 不使用%2格式標識符顯示字元串 196 從字元串中刪除子字元串 197 用另一個子字元串代替子字元串 198 轉換數值的ASCII碼形式 199 判斷字元是否為字母數字 200 字元是否為字母 201 判斷字元是否包含ASCII值 202 判斷字元是否為控制符 203 判斷字元是否為數字 204 判斷字元是否為圖形字元 205 判斷字元是大寫還是小寫 206 判斷字元是否可列印 207 判斷字元是否為標點符號 208 判斷字元是否包含空白符 209 判斷字元是否為十六進制值 210 將字元轉換成大寫形式 211 將字元轉換成小寫形式 212 使用ASCII字元 213 將輸出格式寫進字元串變數 214 從字元串中讀輸入 215 標志字元串以節省空間 216 初始化字元串 第四章 函數 217 函數 218 在函數中使用變數 219 把MAIN當作函數 220 參數簡介 221 使用多參數 222 老式C程序中的參數申明 223 函數返回值 224 RETURN語句 225 函數原型 226 運行時程序庫 227 形參和實參 228 解決名稱沖突 229 返回類型為非INT型的函數 230 局部變數 231 函數如何使用堆棧 232 函數的開銷 233 C如何存儲局部變數 234 申明全局變數 235 避免使用全局變數 236 解決全局和局部變數的名稱沖突 237 更好地定義全局變數的有效范圍 238 傳值調用 239 使用傳值調用防止參數值變化 240 傳址調用 241 獲取地址 242 使用變數的地址 243 改變參數的值 244 只改變指定參數 245 使用堆棧進行傳址調用 246 記住函數變數的值 247 C是如何初始化靜態變數的 248 使用PASCAL調用順序 249 PASCAL關鍵字的影響 250 混合編程示例 251 CDECL關鍵字 252 遞歸函數 253 遞歸階乘函數 254 另一個遞歸的例子 255 進一步理解遞歸 256 直接遞歸與間接遞歸 257 判斷是否要使用遞歸 258 為什麼遞歸函數慢 259 如何消除遞歸 260 將字元串傳遞給函數 261 傳遞指定的數組元素 262 形式參數中的CONST 263 使用CONST不會阻止參數值的修改 264 無界字元串的申明 265 指針的使用與字元串的申明 266 C是如何使用堆棧處理字元串參數的 267 外部變數 268 應用外部變數 269 外部靜態變數 270 VOLATILE關鍵字 271 調用結構和基指針 272 調用匯編語言函數 273 從匯編語言函數中返回值 274 沒有返回值的函數 275 不使用參數的函數 276 AUTO關鍵字 277 范圍 278 范圍的分類 279 名稱空間和標識符 280 標識符的可見性 281 DURATION 282 支持參數個數可變的函數 283 支持個數可變的參數 284 VA-START、VA-ARG和VA-END是如何工作的 285 創建支持多參數多類型的函數 第五章 鍵盤操作 286 從鍵盤讀入字元 287 顯示字元輸出 288 緩沖輸入 289 將鍵盤輸入賦組合字元串 290 聯合使用GETCHAR和PUTCHA 291 記住GETCHAR和PUTCHAR都是宏 292 使用直接I/O讀入字元 293 不顯示字元的直接鍵盤輸入 294 知道何時使用『\R』和『\N』 295 直接輸出 296 將按鍵放回鍵盤緩存 297 使用CPPINTF快速格式化輸出 298 快速格式化鍵盤輸入 299 寫字元串 300 使用直接I/O實現更快的字元串輸出 301 從鍵盤讀入字元串 302 以更快的速度從鍵盤輸入字元串 303 以彩色顯示輸出 304 清除屏幕顯示 305 刪除當前行到行尾的內容 306 刪除屏幕上的當前行 307 定位游標進行屏幕輸出 308 判斷行與列的位置 309 在屏幕上插入空行 310 將屏幕上的文本拷貝到緩沖區 311 將緩沖區中的文本拷貝到屏幕的指定位置 312 判斷文本模式設置 313 控制屏幕顏色 314 指定背景色 315 使用TEXTCOLOR設置前景色 316 使用TEXTBACKGROUND設置背景色 317 控制文本的明暗度 318 決定當前文本模式 319 在屏幕上移動文本 320 定義文本窗口 第六章 數學 321 使用整型表達式的絕對值 322 使用ARCCOSINE反餘弦 323 使用ARCSINE反正弦 324 使用ARCTANGENT反正切 325 求復數的絕對值 326 對浮點值進位舍入 327 使用角的餘弦 328 使用角的雙曲餘弦 329 使用角的正弦 330 使用角的雙曲正弦 331 使用角的正切 332 使用角的雙曲正切 333 整數相除 334 使用指數 335 使用浮點型表達式的絕對值 336 使用浮點余數 337 使用浮點值的尾數和指數 338 計算X*2E的結果 339 計算自然對數 340 計算LOG10X的值 341 判斷最大值與最小值 342 把浮點值分解成整數和小數部分 343 計算Xn的結果 344 計算1010的結果 345 生成隨機數 346 將隨機值映射到指定范圍 347 給隨機數生成器賦初值 348 計算數值的平方根 349 創建定製數學錯誤處理程序 第七章 文件、目錄和磁碟 350 判斷當前盤驅動器 351 選擇當前驅動器 352 判斷可用的盤空間 353 當心DBLSPACE 354 讀入文件分配表FAT信息 355 磁碟ID 356 絕對扇區讀寫操作 357 進行BIOS磁碟I/O 358 測試軟碟機是否准備好 359 應用FOPEN打開文件 360 FILE結構 361 關閉一個打開的文件 362 每次讀/寫文件信息的一個字元 363 文件指針的位置指針 364 判斷當前文件位置 365 文件流 366 文件翻譯 367 CONFIG.SYS文件的FILES=條目 368 使用低級和高級文件I/O 369 文件句柄FILE HANDLES 370 進程文件表PROCESS FILE TABLE 371 進程文件表入口 372 系統文件表 373 顯示系統文件表 374 從流指針中導出文件句柄 375 進行格式化文件輸出 376 重命名文件 377 刪除文件 378 判斷程序如何訪問文件 379 設置文件的訪問模式 380 深入掌握文件屬性 381 檢測文件流錯誤 382 判斷文件的長度 383 刷新I/O流 384 一次關閉所有被打開的文件 385 獲取文件流的文件句柄 386 使用P-TMPDIR創建臨時文件名 387 使用TMP或TEMP創建臨時文件名 388 創建真正的臨時文件 389 刪除臨時文件 390 為文件搜索命令路徑 391 為文件搜索環境入口的子目錄 392 打開TEMP目錄中的文件 393 最小化文件I/O操作 394 在目錄名中使用反斜杠 395 改變當前目錄 396 創建目錄 397 刪除目錄 398 刪除目錄樹 399 建立完全路徑名 400 分解目錄路徑 401 建立路徑名 402 使用低級函數打開和關閉文件 403 創建文件 404 進行低級讀寫操作 405 判斷文件是否結束 406 應用低級文件例行程序 407 為文件句柄翻譯指定模式 408 打開LSEEK定位文件指針 409 打開多於20個的文件 410 使用DOS文件服務 411 獲取文件的日期和時間標記 412 利用位域獲取文件的日期與時間 413 設置文件的日期與時間標記 414 把文件日期和時間設置成當前日期和時間 415 每次讀寫一個字 416 改變文件的長度 417 控制文件打開操作的讀寫模式 418 將緩沖區賦給文件 419 分配文件緩沖區 420 利用MKTEMP創建唯一文件名 421 讀寫結構 422 從文件流中讀取結構數據 423 復制文件句柄 424 強制文件句柄設置 425 把文件句柄和文件流聯系起來 426 文件共享 427 打開文件進行共享訪問 428 鎖定文件內容 429 獲取更精細的文件鎖定控制 430 使用DOS目錄 431 打開目錄 432 讀取目錄入口 433 利用目錄服務讀C:\WINDOWS 434 反繞目錄 435 遞歸讀取磁碟文件 436 判斷當前文件位置 437 打開共享文件流 438 在指定目錄中創建唯一文件 439 創建新文件 440 利用DOS服務訪問文件 441 強制二進制或文本文件打開 442 按行寫文本 443 按行讀文本 444 應用FGETS和FPUTS 445 強制二進制文件翻譯 446 為什麼TEXTCOPY不能拷貝二進制文件 447 判斷文件結尾 448 舍棄字元 449 讀取格式化的文件數據 450 根據當前位置定位文件指針 451 獲取文件句柄信息 452 重新打開文件流 第八章 數組、指針和結構 453 數組 454 申明數組 455 形象表示數組 456 數組的內存需求 457 初始化數組 458 訪問數組元素 459 通過循環訪問數組元素 460 使用常量定義數組 461 把一個數組傳送給函數 462 把數組看作函數 463 區分字元串數組 464 在堆棧中傳送數組 465 判斷數組能存放多少個元素 466 為大數組使用HUGE內存模式 467 權衡數組與動態存儲的利弊 468 多維數組 469 行與列 470 訪問二維數組的元素 471 給二維數組元素賦初值 472 判斷多維數組佔用的內存 473 通過循環顯示二維數組 474 遍歷三維數組 475 初始化多維數組 476 把二維數組傳送給函數 477 把多維數組當作一維數組 478 C是如何存放多維數組的 479 按行存放與按列存放 480 以數組為成員的結構數組 481 聯合 482 使用聯合節省內存 483 使用REGS——一種典型的聯合 484 應用REGS聯合中 485 位欄位結構 486 形象表示位欄位結構 487 位欄位結構的取值范圍 488 在數組中查找指定的值 489 對分查找 490 應用對分查找法 491 對數組進行排序 492 冒泡排序法 493 應用冒泡排序法 494 選擇排序法 495 應用選擇排序法 496 SHELL希爾排序法 497 應用SHELL排序法 498 快速排序法 499 應用快速排序法 500 上述排序方法的遺留問題 501 對字元串數組排序 502 利用LFIND搜索字元串 503 利用LSEARCH搜索數值 504 利用BSEARCH搜索已排序數組 505 利用QSORT對數組排序 506 判斷數組元素的個數 507 把指針理解為地址 508 判斷變數的地址 509 C是如何把數組當成指針的 510 對數組應用取地址運算符 (&) 511 申明指針變數 512 間接訪問指針 513 使用指針值 514 指針與函數參數的使用 515 指針運算 516 指針的增值與減值 517 聯合應用指針引用與增值 518 利用指針遍歷數組 519 利用返回值為指針的函數 520 創建返回值為指針的函數 521 指針數組 522 形象表示字元串數組 523 遍歷字元串數組 524 把字元串數組當成指針 525 使用指向一個指向字元串的指針的指針 526 利用指針申明字元串常量 527 VOID類型指針 528 創建指向函數的指針 529 使用指向函數的指針 530 使用三級指針 531 結構 532 結構是變數申明的模板 533 結構標記是結構的名稱 534 用不同的方式申明結構 535 結構成員 536 形象表示結構 537 應用結構 538 把結構傳遞給函數 539 在函數內部改變結構 540 (*point).member間接引用 541 使用pointer-->member格式 542 使用無標記結構 543 結構定義的范圍 544 初始化結構 545 進行結構I/O 546 使用嵌套結構 547 包含數組的結構 548 創建結構數組 第九章 DOS和BIOS服務 549 DOS系統服務 550 BIOS服務 551 寄存器 552 標志寄存器 553 軟體中斷 554 利用BIOS訪問指針 555 CONTROL+BREAK信息 556 可能的DOS副作用 557 暫時掛起程序 558 控制聲音 559 獲取國家專用的信息 560 磁碟傳輸地址 561 訪問和控制磁碟傳輸區 562 BIOS鍵盤服務 563 獲取BIOS設備列表 564 控制串列口I/O 565 利用BDOS訪問DOS服務 566 獲取擴展DOS錯誤信息 567 判斷BIOS常規內存數量 568 創建遠指針FAR PRINTER 569 把遠端地址分解為段地址和偏移地址 570 判斷自由核心內存 571 讀段寄存器設置 572 內存的類型 573 常規內存 574 常規內存的分布 575 訪問常規內存 576 為什麼PC和DOS限制於1MB 577 從段和偏移量中產生地址 578 擴充內存 579 使用擴充內存 580 擴展內存 581 實模式和保護模式 582 訪問擴展內存 583 高端內存區 584 堆棧 585 各種堆棧配置 586 判斷程序的當前堆棧大小 587 使用-STKLEN控制堆棧空間 588 給內存區域賦值 589 拷貝內存區域 590 拷貝內存區域直到某指定位元組 591 比較兩個無符號字元數組 592 交換兩個相鄰字元串位元組 593 分配動態內存 594 再談類型轉換 595 不再需要時釋放內存 596 利用CALLOC函數分配內存 597 堆 598 解決64KB堆限制 599 從堆棧中分配內存 600 分配巨型數據 601 改變被分配內存區域的大小 602 BRK函數 603 檢測堆 604 快速堆檢測 605 填充自由堆空間 606 檢測特定的堆入口 607 遍歷堆入口 608 訪問指定內存單元 609 向內存中置數 610 PC埠 第十章 內存管理 611 訪問埠值 612 CMOS 613 內存模式 614 微型內存模式 615 小型內存模式 616 中型內存模式 617 壓縮內存模式 618 大型內存模式 619 巨型內存模式 620 判斷當前的內存模式 第十一章 日期和時間 621 獲取當前日期與時間 622 將日期和時間從秒的形式轉換成ASCII碼 623 DAYLIGHT SAVINGS ADJUST MENT 624 延遲若干毫秒 625 判斷程序的耗時 626 比較兩個時間 627 獲取數據串 628 獲取時間串 629 讀BIOS計時器 630 使用當地時間 631 使用格林威治平時 632 獲取DOS系統時間 633 獲取系統日期 634 設置DOS系統時間 635 設置DOS系統日期 636 把DOS日期轉換為UNIX格式 637 利用TIMZONE計算時差 638 判斷當前時區 639 利用TZSET設置時區區域 640 利用TZ環境入口 641 從用戶程序中設置TZ環境入口 642 獲取時區信息 643 以秒鍾的形式設置自1/2/1970午夜以來的系統時間 644 把日期轉換成自1/1/1970以來的秒數 645 判斷日期的儒略歷日期 646 創建格式化日期和時間串 647 PC時鍾類型 第十二章 重定向I/O和進程命令行 648 等候按鍵 649 提醒用戶輸入密碼 650 自己編寫密碼函數 651 輸出重定向 652 輸入重定向 653 聯合使用INPUT和OUTPUT重定向 654 利用STDOUT和STDIN 655 管道運算符 656 GETCHAR和PUTCHAR 657 對重定向輸入進行編號 658 確保信息出現在屏幕上 659 自定義MORE命令 660 顯示重定向行的數目 661 顯示得定向字元的個數 662 創建定時的MORE命令 663 防止I/O重定向 664 應用STDPRN文件句柄 665 把重定向輸出分割到一個文件中 666 應用STDAUX文件句柄 667 在重定向輸入人尋找子串的出現 668 顯示重定義輸入的頭N行 669 命令行變元 670 顯示命令行變元的個數 671 顯示命令行 672 使用引號內的命令行變元 673 從命令行中顯示文件內容 674 把ARGV當作指針 675 C是如何知道命令行的 676 環境 677 把ENV當作一個指針 678 對MAIN的參數使用VOID 679 使用命令行數字 680 出口狀態值 681 為出口狀態過程使用RETURN 682 判斷是否把MAIN申明為VOID 683 在環境中搜索特定入口 684 DOS是如何對待環境的 685 應用ENVIRON全局變數 686 給當前環境添加入口 687 給DOS環境添加元素 688 退出當前程序 689 定義在程序結束時執行的函數 第十三章 編程工具 690 庫 691 重復使用目標代碼 692 編譯C和OBJ文件時出現的問題 693 創建庫文件 694 常用的庫操作 695 列出庫文件中的子例行程序 696 利用庫減少編譯時間 697 庫管理程序的其他功能 698 連接器 699 連接器的功能 700 使用連接映像 701 使用連接器響應文件 702 使用MAKE命令簡化應用程序的創建 703 生成一個簡單的MAKE文件 704 通過MAKE使用多依賴性文件 705 說明用戶的MAKE文件 706 MAKE和命令行 707 在MAKE文件中放置多個依賴性 708 顯現的和隱含的MAKE法則 709 使用MAKE宏 710 預定義MAKE宏 711 用MAKE執行條件進程 712 驗證一個MAKE宏 713 再次包含一個MAKE文件 714 使用MAKE的宏修飾符 715 因錯誤結束MAKE文件 716 關閉命令顯示 717 使用文件BUILTINS.MAK 718 在MAKE中執行出口狀態進程 719 同時激活和改變一個宏 720 為多個依賴文件執行一個MAKE命令 第十四章 高級C語言編程 721 判斷是否有數學協處理器 722 理解CTYPEH,ISTYPE宏 723 控制直接的視像 724 檢查系統和路徑錯誤 725 顯示預定義的錯誤信息 726 決定操作系統版本號 727 理解可移值性 728 執行一個非本地的GOTO 729 獲得進程ID(PID) 730 激活一個內部的DOS命令 731 使用-PSP全局變數 732 在變數申明中使用CONST修飾符 733 使用枚舉類型 734 放置一個枚舉類型來使用 735 理解一個枚舉值 736 分配一個特殊的值給枚舉類型 737 保存和恢復寄存器 738 動態列表簡介 739 申明一個鏈接的列表結構 740 建立一個鏈接的列表 741 一個簡單的鏈表例子 742 理解鏈表轉移 743 創建一個更有用的列表 744 增加一個列表入口 745 插入一個列表入口 746 顯示一個存儲的目錄 747 從一個列表中刪除一個元素 748 使用一個雙向鏈表 749 創建一個簡單的雙向鏈表 750 理解NODE-->PREVIOUS-->NEXT 751 從一個雙向鏈表中移走一個元素 752 在一個雙向鏈表中插入一個元素 753 理解子進程 754 派生一個子進程 755 使用其他的SPAWNLXX函數 756 使用SPAWNVXX函數 757 執行一個子進程 758 使用其他的EXECLXX函數 759 使用EXECVXX函數 760 理解覆蓋 761 理解中斷 762 PC機的中斷 763 使用中斷關鍵字 764 判斷一個中斷向量 765 設置一個中斷向量 766 使能與禁止中斷 767 生成簡單的中斷處理器 768 鏈接一個二次中斷 769 生成一個中斷 770 捕獲PC機時鍾 771 理解致命錯誤 772 C語言中的致命錯誤處理器 773 一個更完全的致命錯誤處理器 774 恢復改變過的中斷 775 生成一個Ctrl+Break處理器 776 在用戶的致命錯誤處理器使用DOS服務 777 使用指令集選擇改善性能 778 直接插入內部函數 779 使能和禁止內在函數 780 理解快速函數調用 781 -FASTCALL參數傳遞的法則 782 理解不變代碼 783 理解冗載入禁止 784 理解代碼緊縮 785 理解循環緊縮 786 理解循環引入和強度削減 787 消除普通的子表達式 788 標准C語言轉換 789 理解C語言的4個基本類型 790 基本類型與派生類型 791 理解初始化值 792 理解連接 793 理解臨時申明 794 申明和定義 795 理解左值LVALUE 796 理解右值RVALUE 797 使用段寄存器關鍵字 798 謹慎使用遠指針 799 理解正常化的指針 800 數學協處理器語句 801 理解變數中的CDECL和PASCAL 802 防止循環包含 第十五章 C++入門 803 C++介紹 804 C++源文件的差異 805 從簡單的C++程序開始 806 理解COUT I/O流 807 使用COUT輸出值和變數 808 用COUT連接不同的數據類型 809 顯示十六進制和八進制數值 810 重定向COUT 811 如果鍾情PRINTF,使用PRINTF 812 輸出 CERR 813 用CIN得到輸入 814 CIN不要使用指針 815 理解CIN如何選擇數據域 816 理解輸入輸出流如何獲得變數類型 817 使用CLOG實現輸出 818 CIN、OCUT、CERR和CLOG是類的實例 819 使用FLUSH操縱符快速輸出 820 理解ISOTREAM.H頭文件包含的內容 821 C++需要函數原型 822 C++增加的新關鍵字 823 C++支持匿名聯合 824 分辨全局范圍 825 提供預設參數值 826 控制COUT的輸出寬度 827 使用SETW設置COUT寬度 828 指定COUT的填充字元 829 左對齊和右對齊COUT的輸出 830 控制COUT顯示浮點數字的數目 831 以小數或科學記數格式顯示數值 832 恢復COUT至默認值 833 設置輸入輸出基數 834 在需要的地方定義變數 835 在函數原型中放置默認參數值 836 使用按位運算符及COUT 837 理解遲緩或短路計算 838 在C++中使用CONST關鍵字 839 在C++中使用ENUM關鍵字 840 理解自由空間 841 用NEW分配內存 842 為多個數組分配內存 843 無自由空間的測試 844 關於堆空間 845 使用FAR指針和NEW運算符 846 釋放內存至自由空間 847 理解C++中的引用 848 給函數傳遞引用 849 防止隱藏對象 850 用三種方法傳遞參數 851 使用引用的規則 852 函數可返回引用 853 使用INLINE關鍵字 854 使用C++的ASM關鍵字 855 用CIN讀字元 856 用COUT寫字元 857 簡單過濾器程序 858 簡單的TEE命令 859 簡單的FIRST 860 更好的FIRST命令 861 文件結束測試 862 用ENDL產生新行 863 理解連接規范 864 理解重載 865 重載函數 866 重載函數的第二個例子 867 避免不明確的重載 868 使用CIN每次讀一行 869 在循環中使用CIN.GETLINE 870 改變NEW運算符的預設處理器 871 用SET-NEW-HANDLER函數設置NEW處理器 872 判斷C++編譯 873 理解C++中的結構 874 結構中定義函數成員 875 在結構內定義成員函數 876 在結構外定義成員函數 877 給成員函數傳遞參數 878 同一結構的多個變數 879 不同結構具有同名函數成員 880 同名成員不同函數 第十六章 對象 881 理解對象 882 理解面向對象編程 883 理解為什麼使用對象 884 把程序分解成對象 885 理解對象和類 886 理解C++的類 887 理解封裝 888 理解多態性 889 理解繼承 890 類和結構的選擇 891 創建簡單類模型 892 實現簡單類的程序 893 定義類構件 894 理解作用域分辨符 895 在申明中使用或省略類名 896 理解PUBLIC:標志 897 理解信息隱藏 898 理解PRIVATE:標志 899 理解PROTECTED:標志 900 使用公用和私數據 901 決定什麼隱藏什麼公開 902 公用方法常稱為介面函數 903 在類外定義類函數 904 在類的內部和外部定義方法 905 理解對象實例 906 對象實例共享代碼

❽ 什麼是C語言

C語言是一門通用計算機編程語言,廣泛應用於底層開發。C語言的設計目標是提供一種能以簡易的方式編譯、處理低級存儲器、產生少量的機器碼以及不需要任何運行環境支持便能運行的編程語言。

盡管C語言提供了許多低級處理的功能,但仍然保持著良好跨平台的特性,以一個標准規格寫出的C語言程序可在許多電腦平台上進行編譯,甚至包含一些嵌入式處理器(單片機或稱MCU)以及超級電腦等作業平台。

二十世紀八十年代,為了避免各開發廠商用的C語言語法產生差異,由美國國家標准局為C語言制定了一套完整的美國國家標准語法,稱為ANSI C,作為C語言最初的標准。

目前2011年12月8日,國際標准化組織(ISO)和國際電工委員會(IEC)發布的C11標準是C語言的第三個官方標准,也是C語言的最新標准,該標准更好的支持了漢字函數名和漢字標識符,一定程度上實現了漢字編程。

C語言是一門面向過程的計算機編程語言,與C++,Java等面向對象的編程語言有所不同。

其編譯器主要有Clang、GCC、WIN-TC、SUBLIME、MSVC、Turbo C等。

語言特點

C語言是一個有結構化程序設計、具有變數作用域(variable scope)以及遞歸功能的過程式語言。

C語言傳遞參數均是以值傳遞(pass by value),另外也可以傳遞指針(a pointer passed by value)。

不同的變數類型可以用結構體(struct)組合在一起。

只有32個保留字(reserved keywords),使變數、函數命名有更多彈性。

部份的變數類型可以轉換,例如整型和字元型變數。

通過指針(pointer),C語言可以容易的對存儲器進行低級控制。

預編譯處理(preprocessor)讓C語言的編譯更具有彈性。

❾ c++中的typedef工具,是干什麼用的,怎麼用,哪位前輩能介紹一下

typedef用法小結- -
這兩天在看程序的時候,發現很多地方都用到typedef,在結構體定義,還有一些數組等地方都大量的用到.但是有些地方還不是很清楚,今天下午,就想好好研究一下.上網搜了一下,有不少資料.歸納一下:
來源一:Using typedef to Curb Miscreant Code
Typedef 聲明有助於創建平台無關類型,甚至能隱藏復雜和難以理解的語法。不管怎樣,使用 typedef 能為代碼帶來意想不到的好處,通過本文你可以學慣用 typedef 避免缺欠,從而使代碼更健壯。
typedef 聲明,簡稱 typedef,為現有類型創建一個新的名字。比如人們常常使用 typedef 來編寫更美觀和可讀的代碼。所謂美觀,意指 typedef 能隱藏笨拙的語法構造以及平台相關的數據類型,從而增強可移植性和以及未來的可維護性。本文下面將竭盡全力來揭示 typedef 強大功能以及如何避免一些常見的陷阱。
如何創建平台無關的數據類型,隱藏笨拙且難以理解的語法?
使用 typedefs 為現有類型創建同義字。
定義易於記憶的類型名
typedef 使用最多的地方是創建易於記憶的類型名,用它來歸檔程序員的意圖。類型出現在所聲明的變數名字中,位於 ''typedef'' 關鍵字右邊。例如:
typedef int size;
此聲明定義了一個 int 的同義字,名字為 size。注意 typedef 並不創建新的類型。它僅僅為現有類型添加一個同義字。你可以在任何需要 int 的上下文中使用 size:
void measure(size * psz);
size array[4];
size len = file.getlength();
std::vector vs;
typedef 還可以掩飾符合類型,如指針和數組。例如,你不用象下面這樣重復定義有 81 個字元元素的數組:
char line[81];
char text[81];
定義一個 typedef,每當要用到相同類型和大小的數組時,可以這樣:
typedef char Line[81];
Line text, secondline;
getline(text);
同樣,可以象下面這樣隱藏指針語法:
typedef char * pstr;
int mystrcmp(pstr, pstr);
這里將帶我們到達第一個 typedef 陷阱。標准函數 strcmp()有兩個『const char *'類型的參數。因此,它可能會誤導人們象下面這樣聲明 mystrcmp():
int mystrcmp(const pstr, const pstr);
這是錯誤的,按照順序,『const pstr'被解釋為『char * const'(一個指向 char 的常量指針),而不是『const char *'(指向常量 char 的指針)。這個問題很容易解決:
typedef const char * cpstr;
int mystrcmp(cpstr, cpstr); // 現在是正確的
記住:不管什麼時候,只要為指針聲明 typedef,那麼都要在最終的 typedef 名稱中加一個 const,以使得該指針本身是常量,而不是對象。
代碼簡化
上面討論的 typedef 行為有點像 #define 宏,用其實際類型替代同義字。不同點是 typedef 在編譯時被解釋,因此讓編譯器來應付超越預處理器能力的文本替換。例如:
typedef int (*PF) (const char *, const char *);
這個聲明引入了 PF 類型作為函數指針的同義字,該函數有兩個 const char * 類型的參數以及一個 int 類型的返回值。如果要使用下列形式的函數聲明,那麼上述這個 typedef 是不可或缺的:
PF Register(PF pf);
Register() 的參數是一個 PF 類型的回調函數,返回某個函數的地址,其署名與先前注冊的名字相同。做一次深呼吸。下面我展示一下如果不用 typedef,我們是如何實現這個聲明的:
int (*Register (int (*pf)(const char *, const char *)))
(const char *, const char *);
很少有程序員理解它是什麼意思,更不用說這種費解的代碼所帶來的出錯風險了。顯然,這里使用 typedef 不是一種特權,而是一種必需。持懷疑態度的人可能會問:"OK,有人還會寫這樣的代碼嗎?",快速瀏覽一下揭示 signal()函數的頭文件 ,一個有同樣介面的函數。
typedef 和存儲類關鍵字(storage class specifier)
這種說法是不是有點令人驚訝,typedef 就像 auto,extern,mutable,static,和 register 一樣,是一個存儲類關鍵字。這並是說 typedef 會真正影響對象的存儲特性;它只是說在語句構成上,typedef 聲明看起來象 static,extern 等類型的變數聲明。下面將帶到第二個陷阱:
typedef register int FAST_COUNTER; // 錯誤
編譯通不過。問題出在你不能在聲明中有多個存儲類關鍵字。因為符號 typedef 已經占據了存儲類關鍵字的位置,在 typedef 聲明中不能用 register(或任何其它存儲類關鍵字)。
促進跨平台開發
typedef 有另外一個重要的用途,那就是定義機器無關的類型,例如,你可以定義一個叫 REAL 的浮點類型,在目標機器上它可以i獲得最高的精度:
typedef long double REAL;
在不支持 long double 的機器上,該 typedef 看起來會是下面這樣:
typedef double REAL;
並且,在連 double 都不支持的機器上,該 typedef 看起來會是這樣:、
typedef float REAL;
你不用對源代碼做任何修改,便可以在每一種平台上編譯這個使用 REAL 類型的應用程序。唯一要改的是 typedef 本身。在大多數情況下,甚至這個微小的變動完全都可以通過奇妙的條件編譯來自動實現。不是嗎? 標准庫廣泛地使用 typedef 來創建這樣的平台無關類型:size_t,ptrdiff 和 fpos_t 就是其中的例子。此外,象 std::string 和 std::ofstream 這樣的 typedef 還隱藏了長長的,難以理解的模板特化語法,例如:basic_string,allocator> 和 basic_ofstream>。
作者簡介
Danny Kalev 是一名通過認證的系統分析師,專攻 C++ 和形式語言理論的軟體工程師。1997 年到 2000 年期間,他是 C++ 標准委員會成員。最近他以優異成績完成了他在普通語言學研究方面的碩士論文。業余時間他喜歡聽古典音樂,閱讀維多利亞時期的文學作品,研究 Hittite、Basque 和 Irish Gaelic 這樣的自然語言。其它興趣包括考古和地理。Danny 時常到一些 C++ 論壇並定期為不同的 C++ 網站和雜志撰寫文章。他還在教育機構講授程序設計語言和應用語言課程。
來源二:(http://www.ccfans.net/bbs/dispbbs.asp?boardid=30&;id=4455)
C語言中typedef用法
1. 基本解釋
typedef為C語言的關鍵字,作用是為一種數據類型定義一個新名字。這里的數據類型包括內部數據類型(int,char等)和自定義的數據類型(struct等)。
在編程中使用typedef目的一般有兩個,一個是給變數一個易記且意義明確的新名字,另一個是簡化一些比較復雜的類型聲明。
至於typedef有什麼微妙之處,請你接著看下面對幾個問題的具體闡述。
2. typedef & 結構的問題
當用下面的代碼定義一個結構時,編譯器報了一個錯誤,為什麼呢?莫非C語言不允許在結構中包含指向它自己的指針嗎?請你先猜想一下,然後看下文說明:
typedef struct tagNode
{
char *pItem;
pNode pNext;
} *pNode;
答案與分析:
1、typedef的最簡單使用
typedef long byte_4;
給已知數據類型long起個新名字,叫byte_4。
2、 typedef與結構結合使用
typedef struct tagMyStruct
{
int iNum;
long lLength;
} MyStruct;
這語句實際上完成兩個操作:
1) 定義一個新的結構類型
struct tagMyStruct
{
int iNum;
long lLength;
};
分析:tagMyStruct稱為「tag」,即「標簽」,實際上是一個臨時名字,struct 關鍵字和tagMyStruct一起,構成了這個結構類型,不論是否有typedef,這個結構都存在。
我們可以用struct tagMyStruct varName來定義變數,但要注意,使用tagMyStruct varName來定義變數是不對的,因為struct 和tagMyStruct合在一起才能表示一個結構類型。
2) typedef為這個新的結構起了一個名字,叫MyStruct。
typedef struct tagMyStruct MyStruct;
因此,MyStruct實際上相當於struct tagMyStruct,我們可以使用MyStruct varName來定義變數。
答案與分析
C語言當然允許在結構中包含指向它自己的指針,我們可以在建立鏈表等數據結構的實現上看到無數這樣的例子,上述代碼的根本問題在於typedef的應用。
根據我們上面的闡述可以知道:新結構建立的過程中遇到了pNext域的聲明,類型是pNode,要知道pNode表示的是類型的新名字,那麼在類型本身還沒有建立完成的時候,這個類型的新名字也還不存在,也就是說這個時候編譯器根本不認識pNode。
解決這個問題的方法有多種:
1)、
typedef struct tagNode
{
char *pItem;
struct tagNode *pNext;
} *pNode;
2)、
typedef struct tagNode *pNode;
struct tagNode
{
char *pItem;
pNode pNext;
};
注意:在這個例子中,你用typedef給一個還未完全聲明的類型起新名字。C語言編譯器支持這種做法。
3)、規范做法:
struct tagNode
{
char *pItem;
struct tagNode *pNext;
};
typedef struct tagNode *pNode;
3. typedef & #define的問題
有下面兩種定義pStr數據類型的方法,兩者有什麼不同?哪一種更好一點?
typedef char *pStr;
#define pStr char *;
答案與分析:
通常講,typedef要比#define要好,特別是在有指針的場合。請看例子:
typedef char *pStr1;
#define pStr2 char *;
pStr1 s1, s2;
pStr2 s3, s4;
在上述的變數定義中,s1、s2、s3都被定義為char *,而s4則定義成了char,不是我們所預期的指針變數,根本原因就在於#define只是簡單的字元串替換而typedef則是為一個類型起新名字。
#define用法例子:
#define f(x) x*x
main( )
{
int a=6,b=2,c;
c=f(a) / f(b);
printf("%d \\n",c);
}
以下程序的輸出結果是: 36。
因為如此原因,在許多C語言編程規范中提到使用#define定義時,如果定義中包含表達式,必須使用括弧,則上述定義應該如下定義才對:
#define f(x) (x*x)
當然,如果你使用typedef就沒有這樣的問題。
4. typedef & #define的另一例
下面的代碼中編譯器會報一個錯誤,你知道是哪個語句錯了嗎?
typedef char * pStr;
char string[4] = "abc";
const char *p1 = string;
const pStr p2 = string;
p1++;
p2++;
答案與分析:
是p2++出錯了。這個問題再一次提醒我們:typedef和#define不同,它不是簡單的文本替換。上述代碼中const pStr p2並不等於const char * p2。const pStr p2和const long x本質上沒有區別,都是對變數進行只讀限制,只不過此處變數p2的數據類型是我們自己定義的而不是系統固有類型而已。因此,const pStr p2的含義是:限定數據類型為char *的變數p2為只讀,因此p2++錯誤。
#define與typedef引申談
1) #define宏定義有一個特別的長處:可以使用 #ifdef ,#ifndef等來進行邏輯判斷,還可以使用#undef來取消定義。
2) typedef也有一個特別的長處:它符合范圍規則,使用typedef定義的變數類型其作用范圍限制在所定義的函數或者文件內(取決於此變數定義的位置),而宏定義則沒有這種特性。
5. typedef & 復雜的變數聲明
在編程實踐中,尤其是看別人代碼的時候,常常會遇到比較復雜的變數聲明,使用typedef作簡化自有其價值,比如:
下面是三個變數的聲明,我想使用typdef分別給它們定義一個別名,請問該如何做?
>1:int *(*a[5])(int, char*);
>2:void (*b[10]) (void (*)());
>3. doube(*)() (*pa)[9];
答案與分析:
對復雜變數建立一個類型別名的方法很簡單,你只要在傳統的變數聲明表達式里用類型名替代變數名,然後把關鍵字typedef加在該語句的開頭就行了。
>1:int *(*a[5])(int, char*);
//pFun是我們建的一個類型別名
typedef int *(*pFun)(int, char*);
//使用定義的新類型來聲明對象,等價於int* (*a[5])(int, char*);
pFun a[5];
>2:void (*b[10]) (void (*)());
//首先為上面表達式藍色部分聲明一個新類型
typedef void (*pFunParam)();
//整體聲明一個新類型
typedef void (*pFun)(pFunParam);
//使用定義的新類型來聲明對象,等價於void (*b[10]) (void (*)());
pFun b[10];
>3. doube(*)() (*pa)[9];
//首先為上面表達式藍色部分聲明一個新類型
typedef double(*pFun)();
//整體聲明一個新類型
typedef pFun (*pFunParam)[9];
//使用定義的新類型來聲明對象,等價於doube(*)() (*pa)[9];
pFunParam pa;

❿ c代碼編程問題,怎樣初始化已定義的結構體

第一章:前言
對於c語言,有人認為它已經落伍了.對於這個問題,仁者見仕,智者見智.的確,c++比c有更強大的諸多優勢.但c++是建立在c之上的.這也是herbert schildt所著的<>在全世界暢銷不衰的原因.更何況,要深入學習linux就必需要有相當的c功底.(這也是我搜集整理本文的根由:-)
現結合個人在編程中的體會,為使新手少走彎路,為老手錦上添花,因此無論你是使用c或c++編程,也無論你是程序設計的初學者還是成熟的專業人員,均會發現,本文將會對你有所收益.當然,我盡力寫得清晰易懂,又不古板.
我愛c.(正如世人愛上帝一樣:-)..

你可以在forum.linuxaid.com.cn上獲得此帖的文本.而其html版本正在趕制之中......

第二章:約定
專業的源程書寫風格.
先看看世界級c大師的源程書寫風格.如 steve maguire 就有許多不錯的建議.

[]倡導使用易於理解的"匈牙利式"的命名約定.
所有的字元變數均以ch開始; 如: char ch_****;
所有的位元組變數均冠以b; 如: byte b_****;
所有的長字變數均冠以l; 如: long l_****;
所有的指針變數均冠以p; 如: char *p_ch_****;
建議類型派生出的基本名字之後加上一個以大寫字母開頭的"標簽".如:
分析 char **ppchmydata;
其讓人一眼就能看出它****一個指向字元指針mydata的指針.
"匈牙利式"命名的最大不足是難念:-(( .但相對於不是總統演講稿的c源程來說,這又算得了什麼?想想看以下的數據命名:
char a,b,c;
long d,e,f;
[]倡導規范書寫.
如果你思如泉湧,而不去也不及顧慮書寫格式,那也沒關系.在將其交出去之前,用cb命令格式化你的源程.雖然源程的格式不會影響到你編譯結果的正確性,但切記,能讓其他的程序員能輕松地閱讀它.否則沒人會理你的.
關於cb命令的更多用法,可以用man cb來參考其手冊頁.
當然除了cb之外,還有更多更好的.但cb是你在任何unix(linux)上都找得到的.更何況它並不差
第三章:開始任務
開始任務之前,先做個深呼吸!
[]其他文檔你准備好了嗎?
你是不是除了c源程之外一無所有了嗎?兵馬未動,糧草先行.你必須先清楚該程序所要完成的功能.在開始寫程序之前,對程序的功能應有規范說明.書寫規范書和確知程序功能的一個方法是先編寫相應的操作手冊.如果你是一人單干,勸你首先寫需求書.切記切記,這對你意味著事半功倍的大好事.
一個實例:我計劃為本行的信貸子功能模塊打一個補丁.我用10周的時間用來寫規劃書,需求書,操作流程,使用說明等等文檔.之後用2周的時間編寫程序,在初步測試(1周)後遞交給各信貸部門測試使用.然後根據反饋的信息再更改相應文檔,並根據文檔修改源程.6個月後發布正式版.
[]一定該遵循ansi標准嗎?
如果你僅使用ansi的標准首標文件,恭喜你,你的程序有著全世界范圍內的廣泛支持和兼容.光明無限.但你必須在通用與專用之間做出取捨,對不起,我幫不了你.
我的原則是:核心用ansi,界面按需而取.這樣在轉換平台時僅需另編用戶界面而已.實用至上嘛.
附:ansi 標准c頭文件

是不是很寒酸?
[]再續前緣?
在得到新任務之後並在開始該新任務之前應馬上回想有哪些是曾經擁有的.舊調重彈遠比另起爐灶來的高效與環保.
[]是否該有自已的庫?
我的答案是應該有自已的特色庫,並與ansi兼容.與3.8不同的是,你僅需在源程序之後附上自已的專用庫就可以了.其次在有了自已的庫後,源碼會很精煉的.不用去羨慕別人了吧.
[]要學會條件編譯.注意你的平台特性.(高手的標志?)
除非你確定你要寫的程序是在某特定的os特定的硬體平台而量身定做.否則應注意數據類型的長度,精度都是不同的,不要想當然.有時甚至是不同的編譯器的差異都要考慮考慮.
....
....(歡迎您來充實此處空白)
....
好了,在任務中,又有哪些細節呢?
[]我是不是葛郎台?
不要那麼吝嗇.在源程序中加入詳盡的注釋以使自己和他人即使在許多年以後仍能讀明白它是什麼樣的程序.
用注釋行分離各個函數.
[]刪除不需要的代碼時要小心.
一個好建議是:使用#ifdef del,而不是簡單地注釋掉甚至是粗暴地直接dd.如果你是使用/* ... */,但一旦要刪除的代碼有很多行,或注釋中以有注釋時,這就可能不那麼好使了.
[]如何給源程序文件命名?
表現特色且不與任何原有應用名相同.一個簡單地方法就是試試看,系統有什麼樣地反應?
[]一次只修改一個地方.
[]一次只編寫一個單一功能的函數。
[]編寫通用程序.
只有當程序編寫完,並且完成了所需要的性能要求之後,再反過頭來優化該程序.
[]不要使用a.out作為結果.你大可以使用與源程相同的可執行文件名.
[]是否一定要用vi編輯?
linux下有許多專用編程編輯器.它們能使你有更高的效率和更低的低級輸入錯誤,但我還是要勸你至少要熟練掌握vi.畢竟vi遍地開花.
[]協同作業.請相信,你不是在孤軍作戰.因此,你有必要熟練掌握一些其它的工具

第四章:使用lint
lint沒有你想像中的那樣糟糕.相反,一旦源程序形成了沒有lint錯誤的形式,將很容易保持下去,並享受到如此而帶來的好處.
[]在cc(gcc)之前就應使用lint.
lint是一語法檢查程序,對於這個多嘴的婆婆來說,你應有足夠的耐心.雖然你知道自已在干什麼,但在cc之前使用lint總是一個好習慣.
[]lint有哪些特色?
在編譯之前使用lint的重要原因是lint不但能發現ansi c中的語法錯誤,而且也能指出潛在的問題或是難於移植於另一機器的代碼問題.除了能指出簡單語法錯誤之外,linut還能基於以下原因指出另外的錯誤:
a.無法達到的語句.
b.沒有進入循環.
c.沒有被使用的變數.
d.函數參數從未使用.
e.沒有賦值之前自動使用參數.
f.函數在有些地方有返回值,但在其他地方不返回.
g.函數調用在不同地方使得參數個數不同.
h.錯誤使用結構指針.
i.模糊使用操作符優先順序.
呵呵呵,挺有用的吧!
[]如何控制lint的輸出?
有時lint會有一大屏一大屏的警告信息.但似乎並未指出錯誤.為了找出潛在的錯誤則需費心費力地瀏覽這些大量的警告信息.
但如果你的程序會分出幾個獨立的模塊,在初級啟動lint時不要用可選項.當對這些模塊進行更改或擴充時,可以忽略與代碼無關的某些警告.為此可用以下選擇項:
-h 對判別是否有錯,類型是否正確不給出啟發式測試.
-v 不管函數中沒有定義的參數
-u 不管被使用的變數和函數沒有定義或定義了但沒有使用.
[]乾脆,在程序中插入指令來影響lint運行.它看樣子有些像注釋.
/*notreached*/ 不可達到的代碼不給信息說明.
/*varargsn*/ 函數的變數個數不作通常的檢查,只檢查開始n個參數的數據類型.
/*nostruct*/ 對下一個表達式不作嚴格類型檢查.
/*argused*/ 下一函數中,不給出沒被使用參數的警告信息.
/*lintlibrary*/ 置於文件的開頭,它將不給出沒被使用函數的警告信息.
關於lint的更多用法,請用man lint來獲知

第五章:使用make
[]什麼是make?
unix(linux)是一個天生的開發平台,我為此感到高興.make是一個強力的工具.它能依賴的源代碼塊並組成一程序,使得很容易建立一可執行程序.make就是這種有依賴關系的部分和代碼之間所作的規格說明.
[] 所有的程序都要使用make?
是的.盡管你只有幾個簡單的模塊,但你需要有一種結構來支持它從簡單走向復雜.除非你的程序已經蓋棺定論.
[]makefile由哪些組成?
makefile由以下幾個部分組成:
注釋.
^^^^
使用#符號插入.make將忽略#之後的任何內容以及其後的return鍵.
變數.
^^^^
make允許定義與shell變數類似的有名變數.比如,你定義了sources=prog.c,那麼該變數的值$(scoures)就包含了源文件名.
依賴關系.
^^^^^^^^
左邊是目標模塊,後接一冒號.再接與該模塊有依賴關系的模塊.
命令.
^^^^
以tab鍵開始(即使用相同數量的空格也不能代替它).
[]makefile示例
下面介紹一個簡單的示例來說明make的用法.假設你的程序有兩個源文件main.c和myc.c,一個位於子目錄include下的頭文件myhead.h,一個庫由****源文件myrout1.c,myrout2.c,myrout3.c產生.
其makefile文件為:
#一個基本的makefile文件.
#其中包括個人的頭文件和個人庫.
headers=include/myhead.h
sources=main.c myc.c
proct=$(home)/bin/tool
lib=myrout.a
libsoures=myrout1.c myrout2.c myrout3.c
cc=cc
cflags=-g
all:$(proct)
$(proct):$(sources)
$(cc)$(cflags) -o $(proct)$(sources)
lint:$(proct)
lint $(sources)$(libsources)
哈哈,挺象shell編程的.如果你與我一樣使用linux下的gcc,那麼只要把上面的cc=cc改為cc=gcc即可.怎麼樣,想來一個更復雜點的嗎?
[]一個更為復雜的makefile
你是否注意到,在上例中,只要啟動make,就會重新編譯所有源代碼.
如果你能看懂以下的makefile,恭喜恭喜,你通關了.
#一個更為復雜的makefile
headers=include/myhead.h
soures=main.c myc.c
objects=main.c myc.c
proct=$(home)/bin/tool
lib=myrout.a
libsources=myrout1.c myrout2.c myrout3.c
libobjects=$(lib)(myrout1.o)$(lib)(myrout2.o)$(lib)(myrout3.o)
include=include
cc=cc
cflags=-g -xc
lint=lint
lintflags=-xc
all:$(proct)
$(proct):$(objects)$(lib)
$(cc)(cflags)-o$(proct)$(objects)$(lib)
.c.o: $(headers)
$(cc)$(cflags) -c i$(include)$<
$(lib):$(headers)$(libsources)
$(cc) $(cflags) -c $(?:.o=.c)
ar rv $(lib) $?
rm $?
.c.c:;
lint: $(proct)
$(lint)$(liniflags)$(sources)$libsources)

第六章:優質無錯編程
親愛的,檢查一下,你是否注意到了以下的細節?也就是說,你是否是一個合格的,能編寫優質無錯代碼的程序員?要永遠記住,編寫無錯代碼是程序員的責任,而不是測試員.(摘錄於本人的"細節頁",因此本節將永遠不會保持完整,歡迎您來充實她)
[]所有程序員至少出現過的一個錯誤:
if(a=3){......}如果a等於3,那麼......
你至少要養成這樣的習慣:當判斷一個變數與一個常量是否相等時,將常量寫在前面.這樣即使你一不小心寫成這樣:if(3=a){......}在cc 之前就可以很容易發現它.
[]老調重彈:邏輯操作符的優先權.
我不願多嘴.總之,如果你一定要編寫如下代碼時:
if(a&0x1&&b&0x2){......}
你的手頭最好有一本詳盡的指南.或者你是這方面的專家.
[]盡量不使用int數據類型.
這僅是一個忠告.你大可使用char,short,long數據類型.若干年以後,當你成長為高手之時,你會發現此時我的良苦用心.
[]對於非整型函數一定要完整定義.
如 long float jisuan(char charr[],int chnum)
{ long float lmydata;
...
...
return(lmydata); }
[]對於非整型函數的輸入要當心.
如 long float lfnum;
...
...
scanf("%lf",&lfnum);
[]float 型的有效數字為7位.當多於7位時,第8位及以後的位將不準確,可以將其定義為long float型.
[]文件的輸入出盡量採用fread fwrite函數.只有當另有用途時才用fprintf fscanf 函數

熱點內容
密碼鎖寫什麼最好 發布:2025-05-15 19:05:31 瀏覽:782
5的源碼是 發布:2025-05-15 19:04:07 瀏覽:719
c語言創建的源文件 發布:2025-05-15 18:54:08 瀏覽:611
3個數字密碼鎖有多少種 發布:2025-05-15 18:49:48 瀏覽:684
壓縮包手機打開 發布:2025-05-15 18:37:34 瀏覽:217
安卓取消耳機模式怎麼取消 發布:2025-05-15 18:24:24 瀏覽:59
氣球怎麼解壓視頻 發布:2025-05-15 18:20:00 瀏覽:783
電腦軟體密碼怎麼設置密碼 發布:2025-05-15 18:09:07 瀏覽:107
android應用是否運行 發布:2025-05-15 18:02:40 瀏覽:10
java排序list 發布:2025-05-15 18:02:40 瀏覽:298