如何精通C語言

精通C語言是有難度的,卻也不是沒有方法。

首先,內存意識。

C語言和其他高級語言不一樣,它的很多操作都是直接面向內存(面向硬體)。

困難的是,對於C語言,不論是數據類型、操作符、語句、函數,都或多或少、或簡單或複雜地通過地址操作內存。

幸運的是,一旦掌握內存,代碼功能會非常強大,執行效率非常之高。

舉個例子。

如何把一個二進位數轉換成十進位以字元的形式輸出?

做過十進位位數分離的程序員都知道,可以採取「模10再除10」的方法把一個二進位數按十進位分離每一位

嘗試著去理解下面的程序。

while(putchar(value % 10 + 0) && (value /= 10))

;

putchar()函數的原型是int putchar(int ch);執行結束返回1。

這個代碼風格已經算優質了,只不過這樣是倒序的,想要實現正序排列可以使用遞歸

void binary_to_ascii (unsigned int value)

{

unsigned int quotient;

quotient = value / 10;

if(quotient != 0)

binary_to_ascii(quotient);

putchar(value % 10 + 0);

}

但是當你明白了字元串常量的原理後,你可能會寫出這樣不平凡的代碼。

while(putchar( "0123456789" [value % 10] ) && (value /= 10))

;

這是因為,一個字元串常量存儲在內存的某一位置,調用它的時候,並沒有把整個字元串傳遞進去,而是只傳遞一個指針常量(一個地址),然後執行和數組相同原理的下標引用。沒錯,你可能猜到了,也猜對了,數組名也是一個指針常量。

其次,掌握原理。

掌握哪些原理?數據類型、操作符是重點。

典型的,指針、數組、結構體、一些重點操作符。

以操作符為例:

++操作符:a++和++a它們的機制分別是什麼?

a++:我們稱為後++,首先a生成一份拷貝,然後a執行++,最後返回拷貝。返回的拷貝值是舊a,新a已經執行了++操作。

++a:我們稱為前++,首先a執行++,然後a生成一份拷貝,最後返回拷貝。a先執行++,再拷貝,返回的拷貝就是新a。

如何理解拷貝?簡單學習彙編語言,了解機器內部的運算方式,就可以理解。

&&和||操作符:先執行左表達式,再執行右表達式,如果左表達式就能確定整個結果,則不執行右表達式。

如果你知道while語句scanf()putchar()的原型,那麼下面這個語句將不難理解。

while(scanf("%d", ch) && ch != EOF)

putchar(ch);

scanf()換成getchar()也可以,這裡只是想提醒大家scanf()的原型。

如果你足夠理解for語句和表達式,看下面這個代碼。

int a[n], *vp;

for(vp = a; vp < &a[n]; ){

*vp++ = 0;

}

這個代碼有兩個問題:功能是什麼?是否有錯誤?

第一個問題:功能是實現數組的初始化。

第二個問題:沒有錯誤。其一,&a[n],指向數組外,指向並不會有錯誤,但是不能執行間接訪問,即*vp=a[n]是非法的。其二,for語句,括弧內需要三個表達式,最後一個不寫,表示空表達式,空表達式也是表達式。

最後,清晰概念。

什麼是預處理、什麼是表達式、什麼是語句、什麼是函數、什麼是操作符、什麼是數據類型。

只有真正能區分它們的不同,你才能理解各種複雜的代碼。

p=&a和*p=&a,在一定的語句下,都可以是正確的,它們又有什麼不同?

什麼是聲明、什麼是定義、什麼是調用。

它們作用於不同的數據類型是否有本質上的區別。

比如說,聲明一個變數,就要分配內存。聲明一個結構體,不會分配內存,只有定義一個實體的時候,才分配。它們的實現原理不同,具體使用就會有細微的差別。

什麼是常量、什麼是變數、什麼是指針常量char * cnost f、什麼是常量指針char const *f、什麼是指針函數char *f()、什麼是函數指針char (*f)(),等等。

區分它們,只有一個辦法,掌握操作符優先順序,變數f先和什麼結合,f就是什麼,前面剩下的,就是返回類型。

char * cnost f:f是常量,並且是指針,返回類型為普通的char。指針常量,指針的值不能變,指針指向的數據可變,比如數組名

char const *f:f是普通的指針,返回類型是char const。指針的值可變,指針指向的數據不能變。常量指針,面向介面編程常用的方法。

char *f():()的優先順序比*高,所以f是一個函數,返回類型是一個char型指針,返回類型為指針的函數。指針函數,動態分配內存的好方法。

char (*f)():同為(),優先順序相同看結合性,自左向右。f是一個指針,指向一個返回為char型的函數。函數指針,回調函數的實現方法。

掌握了上面的知識就能精通C語言么?

顯然是遠遠不夠的,我只是從我的角度總結了幾個方面,給出一些建議。

而真正要做到精通,只有不斷的學習。

關於柚子編程

致力於零基礎入階編程世界,一周一更

每周日中午12:00準時更新

喜歡記得來一個贊

推薦閱讀:

第18篇 它不是人,它是恐豬
4.說些和自學有關的。
學習計算機的一些資源分享
對於一些自學編程QQ群的一些看法與感悟

TAG:C編程語言 | 編程 | 自學編程 |