如何精通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群的一些看法與感悟