C語言基礎(一)

2021-07-24 17:16:25 字數 4329 閱讀 8160

參看: 《c程式語言》第二版

上面的參考書籍是主要的學習手段,下面只是針對一些特定的問題進行論述,這些特定的問題,書中可能沒有提到。

乙個物件的型別決定著該物件可取值的集合以及可以對該物件施行的運算。

問題1:我們知道基本的資料型別有四種char,int,float,double。 型別修飾符也有四種short, long, signed, unsigned。 型別修飾符和基本資料型別的組合並不是都是有效的,其中修飾符是可以並存的,前提是這種表示是有意義的,比如」unsigned long int」,還有,修飾符或者基本型別定義的順序是無關的,比如「unsigned long int」和「long int unsigned 」是等同的,這些組合詳細可以參考《c程式語言》第二版的第二章。現在的問題是char型別能否表示所有的標準的ascii碼表的值?

答:基本的資料型別都有預設的型別修飾符,但是到底是哪個型別修飾符是依賴機器的,char型別就是個例子。signed char的取值範圍是-128~127, unsigned char 的取值範圍是0~255。標準的ascii碼表只使用了7位,它的取值範圍是0~127。從上面的分析可以得知char型別能表示所有的ascii碼標的值。

補充:const的修飾符是後來加上的,對於這個修飾符我們也會有乙個問題。

問題2:指標型別的變數定義不同於基本型別變數的定義。基本型別變數的定義基於兩部分,前半部分是基本型別、型別修飾符和儲存型別(auto,static等 ,後面關於這個還有幾個問題),第二部分是變數名。指標型別變數的定義是分為三個部分,第一部分和基本型別變數的定義的前半部分是相同的,第二部分是符號」「,第三部分是變數名。比如,我們定義乙個整型指標型別的變數」int p;」。我們的問題是const char * p; char const * p; char * const p; 三個表示方式有什麼差別?

答:要解決這個問題,我們需要清楚三件事情,基本型別的前半部分是否有順序的問題?第二件事情是修飾符語義的表達範圍?第三件事情 、*p 和 p 有什麼區別?

基本型別的前半部分是不依賴順序的,但是我們有一些編寫習慣的問題,比如我們往往只會寫」const int a;」,而不是「int const a;」 。

修飾符的語義表達範圍涉及到剛剛我們定義的三部分,修飾符只能修飾之後的部分,比如說,如果const 在第一部分,那麼const能修飾第二部分和第三部分,如果const 在第二部分和第三部分之間,那麼const只能修飾第三部分。

*p和p是有區別的。 「*」是表示間接引用運算子,它不是型別修飾符,所以我把它放在了第二部分,嚴格意義上來說,第二部分和第三部分是不能有任何其他的修飾符的,但是後來出現了const,const的語義是用來保證變數空間值的不可更改性。*p和p代表的不同的意思,*p代指間接引用空間,p本身代表指標變數的空間。

從上面的論述我們很容易得出下面的三個結論:

1. const char *p 和 char const * p是等價的。

2. const char *p 表示const修飾 *p空間,所以意思是*p空間的值不能被修改。

3. char * const p表示const修飾p空間,所以意思是p空間的值不能被修改。

驗證const char *p;

/*****

*****

*****

*****

*****

*****

*****

*****

*****

*****

*****

*****

*****

*****

***> file name: main.c

> author: mhsheng

> mail:[email protected]

> created time: wed 16 nov 2016 06:07:52 pm cst

*****

*****

*****

*****

*****

*****

*****

*****

*****

*****

*****

*****

*****

*******/

#include

#include

intmain(int argc, char **argv)

針對上面的**,如果使用gcc main.c我們會得到如下的錯誤:

main.c: in

function 『main』:

main.c:18:2: error: assignment of

read-only location 『*pc』

pc[0] = 'x';

^

驗證char * const p;

/*****

*****

*****

*****

*****

*****

*****

*****

*****

*****

*****

*****

*****

*****

***> file name: main.c

> author: mhsheng

> mail:[email protected]

> created time: wed 16 nov 2016 06:07:52 pm cst

*****

*****

*****

*****

*****

*****

*****

*****

*****

*****

*****

*****

*****

*******/

#include

#include

intmain(int argc, char **argv)

針對上面的**,如果使用gcc main.c我們會得到如下的錯誤:

main.c: in

function 『main』:

main.c:18:2: error: assignment of

read-only variable 『pc』

pc = d;

^

問題3:const在c語言中有什麼用處?

答:const是後來才加入c語言標準中的,從某個方面來說它是後媽生的孩子,因為是後媽生的,所以這個孩子會很調皮(簡單地說就是它的使用語義場景並不是都是定義好的),對於調皮的孩子我們的處理方式是,只關心一些正常的case使用,不關心一些開發中不會用到的場景,比如說我想把乙個const指標強制轉換成乙個非const的指標,我認為這是非法使用,const嚴格意義上說不是變數修飾符,它是用來限定不同通過該變數來修改變數所指向的記憶體空間的值

在c語言中,有三種用法:

1. 修飾變數。

2.修飾函式引數。

3.修飾函式返回值。

在c++語言中,多了一種用法:

4.修飾成員函式,限定在成員函式中不可修改非靜態成員變數的值。

依據我剛才對const的語義的理解,const修飾的int變數,不能作為陣列的常量表示式。比如:

const

intlen = 10;

int a[len] = ;

個人認為這是非法的,但是在c++中,這種行為確實是可行的,雖然c++上說了這種方式的n種好處,但是個人還是不推薦使用,從某種意義上來說len就是乙個常量,但是依據我對const的理解,len其實還是乙個變數,而陣列的定義是需要常量表示式的,所以個人認為這是不科學的。產生這種分歧的根本原因是,const是後媽生的。

問題4:型別轉換的規則是個非常複雜的過程,主要的原因是變數型別的所能表示的值集合空間是不一樣的,有些值集合事有包含關係,可是有些集合只是有交叉。那麼為什麼會有型別轉換的需求呢?

答:c語言中的多目操作符要求操作的物件型別必須保持一致,這樣操作符產生的結果才會確定下來。簡單的說為了防止二義性。如果沒有型別轉換,我們就無法知道乙個整型數和乙個浮點型想加,最終的結果是乙個浮點型的還是乙個整型的?

我們的轉換使用從小的集合轉到大的集合,從有符號轉到無符號,從整型轉到浮點型。這就是基本的轉換方式,但是具體到特定情況,就會變得很複雜,如果是負值從小的型別轉換到大的型別,高位是採用「符號擴充套件」,還是採用「0值填充」呢?

C語言基礎一

命令語句都是在蘋果終端下使用的。編譯 cc c hello.c 把源 變成二進位制檔案 目標檔案 cc one.o two.o three.o 預設生成可執行檔案a.out cc o task one.o 生成可執行檔案task 執行 1 在終端輸入 a.out 2 雙擊a.out檔案,選擇用終端執...

c語言基礎(一)

雙精度和單精度 數字後帶f的是單精度float,不帶的是雙精度double,單精度儲存的範圍是雙精度的倍數,兩種都屬於浮點型,當整數部分位數太多時候,小數部分很可能被遺失。ascii碼中0 31和127是不可以在鍵盤中輸入的。除了轉義字元 字元常量 a 單引號包含乙個 x和兩個16進製制數 任何0 ...

C語言基礎 一

一 語言的發展 1 機器語言 特點 a.或稱為二進位制 語言,計算機可以直接識別,不需要做任何翻譯.b.是第一代的計算機語言.c.使用時難記憶難操作編寫出來的程式全是由0和1的數字組成,直觀性差,難以閱讀,不僅難學,難記難檢查,又缺乏通用性.2.十進位制轉為二進位制 將十進位制除以2的餘數寫出來 直...