title: "《C和指針》——C語(yǔ)言補(bǔ)漏(基本用法篇)"
date: 2014-05-14 19:06:57
categories: 韋編三絕
這本書應(yīng)該是我最后一次買盜版的經(jīng)典書籍了筹吐,買了這本書后我就寫下了學(xué)生應(yīng)盡量購(gòu)買正版,發(fā)誓以后都在正規(guī)的書店(包括網(wǎng)上書店)買書绒极。
本來(lái)以為這本書的內(nèi)容挺少的骏令,但當(dāng)讀到指針的部分發(fā)現(xiàn)我以前了解的真的很少,還好我上學(xué)期認(rèn)真學(xué)過(guò)《數(shù)據(jù)結(jié)構(gòu)》這門課垄提,對(duì)指針的使用還算熟練榔袋,不然光靠以前自學(xué)的譚浩強(qiáng)的C語(yǔ)言和課堂上教的,根本就只能算是一個(gè)只知道C語(yǔ)言這個(gè)東西的人铡俐。
至于這本書的閱讀時(shí)間凰兑,我覺(jué)得我的時(shí)間并不正確,這本書應(yīng)該是在C語(yǔ)言基礎(chǔ)學(xué)完后审丘,在數(shù)據(jù)結(jié)構(gòu)之前來(lái)學(xué)習(xí)吏够,不僅可以深入理解一下C語(yǔ)言的精髓,還可以順利過(guò)渡到數(shù)據(jù)結(jié)構(gòu)的學(xué)習(xí)滩报。
在這里就以前我不了解的一些C語(yǔ)言知識(shí)做一些歸納(不過(guò)這里很多都是一些以前沒(méi)見(jiàn)過(guò)的函數(shù)以及一些用法锅知,當(dāng)然這些函數(shù)或者是用法并不是罕見(jiàn)的,只是在學(xué)生中比較罕見(jiàn)罷了脓钾,我在網(wǎng)上看過(guò)很多高手的代碼售睹,發(fā)現(xiàn)有一些還是挺常用的)。
-
要從邏輯上刪除一段C代碼可训,更好的辦法是使用#if指令昌妹。這樣可以防止在一段內(nèi)部已經(jīng)有注釋的代碼外面加上注釋所引起的注釋不匹配的問(wèn)題:
#if 0 statements #endif
EOF是一個(gè)整型值,在很多讀入字符的情況下握截,如果要判斷輸入是否結(jié)束飞崖,需要把字符讀入為整型值,這樣可以判斷輸入是否結(jié)束谨胞。
程序會(huì)使用一個(gè)運(yùn)行時(shí)堆棧固歪,它用于存儲(chǔ)函數(shù)的局部變量和返回地址。程序同時(shí)也可以使用靜態(tài)內(nèi)存胯努,存儲(chǔ)與靜態(tài)內(nèi)存中的變量在程序的整個(gè)執(zhí)行過(guò)程中將一直保留著他們的值牢裳。
標(biāo)準(zhǔn)規(guī)定了幾個(gè)特殊的三字母詞术瓮,比如??(代表[,不過(guò)這個(gè)應(yīng)該很少見(jiàn)贰健,至少我之前一直沒(méi)碰到這種情況
-
如果要?jiǎng)?chuàng)建新的類名胞四,應(yīng)該使用typedef而不是#define,因?yàn)楹笳邿o(wú)法正確處理指針類型伶椿,例如:
#define ptr char* ptr a,b;
上面代碼會(huì)使a成為一個(gè)char指針辜伟,而b卻被聲明為一個(gè)char
-
在定義常量的時(shí)候我們應(yīng)該使用#define而不是const:
#define MAX_ELEMENTS 50 int const max_elements 50;
因?yàn)橹灰试S使用字面值的地方都可以使用前者,比如聲明數(shù)組的長(zhǎng)度脊另,const變量只能用于允許使用變量的地方导狡。
鏈接屬性:分為3種——external(外部)、internal(內(nèi)部)和none(無(wú))偎痛。沒(méi)有鏈接屬性的標(biāo)識(shí)符(none)總是被當(dāng)作單獨(dú)的個(gè)體旱捧,也就是說(shuō)該標(biāo)識(shí)符被當(dāng)作獨(dú)立不同的實(shí)體。屬于internal鏈接屬性的標(biāo)識(shí)符在同一個(gè)源文件內(nèi)的所有聲明都指同一個(gè)實(shí)體踩麦,但位于不同源文件的多個(gè)聲明則分屬不同的實(shí)體枚赡。最后,屬于external鏈接屬性的標(biāo)識(shí)符不論聲明多少次谓谦,位于幾個(gè)源文件都表示同一個(gè)實(shí)體贫橙。
凡是在任何代碼塊之外聲明的變量總是存儲(chǔ)于靜態(tài)內(nèi)存中,也就是不屬于堆棧的內(nèi)存反粥,這類變量稱為靜態(tài)變量卢肃。
標(biāo)準(zhǔn)說(shuō)明無(wú)符號(hào)值的所有移位操作都是邏輯移位,但對(duì)于有符號(hào)值才顿,到底是采用邏輯移位還是算術(shù)移位取決于編譯器莫湘。也就是說(shuō)一個(gè)程序如果所使用了有符號(hào)數(shù)的移位操作,他就是不可移植的郑气。
C函數(shù)可以理解為所有的參數(shù)均以“傳值調(diào)用”的方式進(jìn)行傳遞幅垮,傳遞數(shù)組時(shí)也傳遞的是指針的值。
只要有可能竣贪,函數(shù)的指針形參都應(yīng)該聲明為const
不要使用strlen來(lái)相減军洼,因?yàn)閟trlen是無(wú)符號(hào)數(shù)巩螃,那么相減的結(jié)果必然也是無(wú)符號(hào)數(shù)演怎,所以像
if( strlen(x) - strlen(y)= 0 )
這種用法就是錯(cuò)的,因?yàn)榻Y(jié)果永遠(yuǎn)都是大于等于零注重可移植的程序應(yīng)該避免使用位段避乏。任何可以用位段實(shí)現(xiàn)的任務(wù)都可以使用移位和屏蔽來(lái)實(shí)現(xiàn)爷耀。
編譯器為一個(gè)結(jié)構(gòu)變量的成員分配內(nèi)存時(shí)要滿足他們的邊界對(duì)齊要求。在實(shí)現(xiàn)結(jié)構(gòu)存儲(chǔ)的邊界對(duì)齊時(shí)拍皮,可能會(huì)浪費(fèi)一部分內(nèi)存空間歹叮。根據(jù)邊界對(duì)齊要求降序排列結(jié)構(gòu)成員可以最大限度地減少結(jié)構(gòu)存儲(chǔ)中浪費(fèi)的內(nèi)存空間跑杭。
在程序中,數(shù)組的長(zhǎng)度一般是根據(jù)運(yùn)行后決定的咆耿,所以最好使用動(dòng)態(tài)內(nèi)存分配德谅。
幾個(gè)預(yù)定義符號(hào):
FILE: 進(jìn)行編譯的源文件名
LINE: 文件當(dāng)前行的行號(hào)
DATE: 文件被編譯的日期
TIME: 文件被編譯的時(shí)間
STDC: 如果編譯器遵循ANSI C,其值就為1萨螺,否則未定義如果相同的代碼需要出現(xiàn)在程序的幾個(gè)地方窄做,通常的做法是將它實(shí)現(xiàn)為一個(gè)函數(shù),而不是宏#define
-
條件編譯:可以允許選擇某條語(yǔ)句或某組語(yǔ)句進(jìn)行翻譯或者被忽略慰技,這常用語(yǔ)本地調(diào)試:
#if constant-expression statements #endif
文件包含:如果是庫(kù)文件一般用<>椭盏,如果是本地文件一般用””
-
刪除多重包含引發(fā)的危險(xiǎn):
#ifndef _HEADERNAME_H #define _HEADERNAME_H 1 /* ** All the stuff that you want in the header file */ #endif
絕大多數(shù)流是完全緩沖的,意味著“讀取”和“寫入”實(shí)際上是從一塊被稱為緩沖區(qū)的內(nèi)存區(qū)域來(lái)回賦值數(shù)據(jù)吻商。用于輸出流的緩沖區(qū)只有當(dāng)它寫滿時(shí)才會(huì)被刷新到設(shè)備或文件中掏颊。也可使用fflush迫使緩沖區(qū)的數(shù)據(jù)立即寫入,不管它是否已滿艾帐。
函數(shù)庫(kù)為I/O所提供的接口稱為流乌叶。
fgets函數(shù)比gets函數(shù)更為安全,它把緩沖區(qū)長(zhǎng)度作為參數(shù)之一柒爸,可以保證一個(gè)長(zhǎng)輸入行不會(huì)溢出緩沖區(qū)枉昏,gets函數(shù)會(huì)去除它所讀取的行的換行符,puts函數(shù)在寫入到緩沖區(qū)的文本后面加上一個(gè)換行符揍鸟。