tft每日頭條

 > 生活

 > c語言必背入門代碼解釋

c語言必背入門代碼解釋

生活 更新时间:2024-07-26 11:09:04
21 函數可以嵌套定義和調用嗎?

函數不可以嵌套定義,但是可以嵌套調用。

c語言必背入門代碼解釋(小白入門C語言20問20答2)1

22 變量的定義和聲明是一樣的嗎?

不一樣。變量的定義是指要分配存儲空間的,而聲明并不需要;此外,一個變量隻能被定義一次,不能重複定義多次,但是可以多次聲明。以外部變量為例來說,一個外部變量隻能在所有函數的外面定義一次,但是它可以在函數内外被多次聲明。對變量的初使化隻能在定義時進行,而不能在聲明的時候進行。

23 指針變量的基類型具有什麼作用?

指針變量的取值都是内存單元的地址,即是一個無符号的整數,就其取值而言,指針變量是沒有類型概念的。那麼指針變量的基類型是什麼意思呢?

實際上,指針變量的基類型是指示當使用指針變量操作内存單元時,需要操作多少個内存單元。另外,指針算術運算時,編譯器也需要以基類型為基礎來參與運算。編譯器在處理編譯一個單元的int與一個單元的float是不同的。例如,假設p是一個指針,表達式p 是表示将指針p往後移動一個元素所占的存儲單元,而到底是幾個字節要由p所指示的元素本身的數據類型所決定。例如:int *p1; char *p2; 此時,p1 表示p1往後移動兩個字節,而p2 表示p2往後移動一個字節。

24 表達式*p 是自增 p 還是 p 所指向的變量值?

因為 和*運算符的優先級相同,因此,這個表達式的運算順序要根據其結合方向來判斷。由于其結合方向應該是自右向左,因此上面表達式等價于*(p )。那麼,它的含義就應該是自增p,但是返回值是p自增之前所指向的變量的值,即*p的值。由于類似情況會經常遇到,所以也提醒讀者應該養成在适當的時候使用括号的習慣,以免産生程序歧義。

25 什麼是空指針?

空指針與同類型的其它所有指針都不相同, 也與任何對象或函數的指針都不相等。也就是說, 用取地址操作符&永遠也不能得到空指針, 同樣對 malloc() 的成功調用也不會返回空指針, 除非調用失敗, malloc() 才返回空指針。

實際上,空指針表示“未分配”或者“尚未指向任何地方”的指針。它在概念上不同于未初始化的指針。因為,空指針可以确保不指向任何對象或函數,而未初始化指針則可能指向任何不确定的地方。

C語言中的NULL是C語言中定義的預處理宏,它一般代表0 或者 ((void *)0),用于表示一個空指針。在C程序中,NULL實際上和0完全等價的。需要注意的是:NULL隻能用作指針常量來使用。

*void:一種通用指針未确定類型的指針, 可以通過類型轉換強制轉換為任何其它類型的指針。

26 數組名和指針是否相同?

并不相同。例如有如下定義:char a[ 4];char *p;此時,字符數組名a是一段确定數據空間的起始地址,但字符指針p卻還沒有指向任何确定的空間。此外,指針是可以移動的,數組名卻不能移動。

但是,在很多C語言的教材中都有數組名和指針“等價”的說法。需要注意的是,這裡的等價不是指的相同,隻是想說明在算法定義中可以用指針的形式來訪問數組的數據,這樣做起來操作更方便。尤其是當使用數組名作為函數參數的時候,往往是可以采用與之對應的指針來替換的。

27 C語言如何實現動态數組?

C語言中是不允許定義動态數組的,即數組中元素個數的大小必須在定義數組時确定。在以下的數組的定義語法中:

數據類型 數組名[元素個數表達式]

元素個數表達式必須是常量表達式,其中不能含有變量。因此在C程序中不能根據程序運行的狀态動态在定義元素個數可變的數組,例如以下的數組定義是錯誤的,在編譯時将産生語法錯誤:

int n; scanf("%d",&n); int a[n];

然而,在有些問題中數據的個數是可變的,如果數組定義得過小或過大,都不能滿足程序的需要。此時可以通過C語言的動态内存分配功能來實現對動态數組的模拟。

動态分配内存的含義是指:在程序運行時根據需要從操作系統申請内存空間,在使用完畢後再釋放歸還給系統。動态分配内存使用函數malloc,其原型聲明為:

void * malloc(unsigned size)

其中size表示需要分配的内存空間的字節數大小。

malloc函數的返回值是指向所分配的内存單元的首地址指針。由于在分配内存時,系統并不知道用戶将要如何使用這些内存單元,因此malloc函數的返回值為void *,即無類型的指針。在用戶程序中應根據需要将其強制轉換為适當的基類型。例如從内存中分配用于存放5個整數的内存空間,并将其首地址指針賦值給整型指針變量p,應使用以下的代碼:

int * p; p=(int *)malloc(5*sizeof(int));

28 一個指針變量到底會分配多少内存空間?

當定義了一個指針變量以後,實際上隻是給這個指針分配了能夠容納指針本身的内存,而沒有分配指針所指向的内容的存儲空間。例如:int *p;定義之後,系統為指針p分配的内存空間為sizeof(int *),而并沒有分配一個整型變量所占的字節數。

29 枚舉元素的值是多少?

在C語言中,枚舉元素是作為常量來處理的,程序編譯時會給一個枚舉變量中的元素依次賦初值0,1,…。但是,如果在定義時人為的改變了某個枚舉元素的值,那麼,其後面所有元素的值也會跟着改變。

30 程序設計中的文件概念

在計算機系統中,不論是程序還是數據都是存儲在外部存儲器中的文件。文件既是操作系統的重要概念,也是程序設計中的重要内容。在實際的數據處理問題中,大量的數據往往都是事先存儲在具有一定格式的數據文件中,程序通過讀寫文件完成數據的取得和結果的保存。

根據文件的組織形式,文件分為ASCII文件和二進制文件兩種基本類型,C語言中分别使用不同的方式操作這兩類文件。

當程序需要操作文件中的數據時,應首先将文件打開,然後進行讀寫操作,當操作完成後,應及時關閉文件,以保證文件中數據的安全性和完整性。

在C語言中的文件操作中,對于每一個打開的文件都使用一個稱為“文件類型指針”的指針指向該文件,當文件被成功打開後,通過相應的文件類型指針即可以對文件進行讀操作,而無須再關心文件的物理存儲位置、文件名等相關文件信息。

為了表示已經打開的文件的相關信息,C語言在stdio.h中定義了FILE結構體,其數據成員定義如下(以下出自stdio.h):

c語言必背入門代碼解釋(小白入門C語言20問20答2)2

當打開一個文件後,即會産生一個以FILE為基類型的指針FILE *,程序中通過這個指針完成對文件的讀寫操作。

所謂打開文件,就是将指針指向要使用的文件,打開之後才能通過這個文件指針來讀寫文件的内容;而關閉文件,就是把文件指針和文件脫鈎,以後不能再使用這個文件指針訪問該文件。

通過調用函數fopen可以以不同的方式打開一個文件,并返回指向文件的FILE指針。fopen函數的原型聲明為:

FILE * fopen(文件名,打開方式)

31 static全局變量與普通的全局變量有什麼區别?static局部變量和普通局部變量有什麼區别?static函數與普通函數有什麼區别?

答:全局變量(外部變量)的說明之前再冠以static 就構成了靜态的全局變量。全局變量本身就是靜态存儲方式, 靜态全局變量當然也是靜态存儲方式。 這兩者在存儲方式上并無不同。這兩者的區别雖在于非靜态全局變量的作用域是整個源程序,當一個源程序由多個源文件組成時,非靜态的全局變量在各個源文件中都是有效的。 而靜态全局變量則限制了其作用域, 即隻在定義該變量的源文件内有效, 在同一源程序的其它源文件中不能使用它。由于靜态全局變量的作用域局限于一個源文件内,隻能為該源文件内的函數公用, 因此可以避免在其它源文件中引起錯誤。

從以上分析可以看出,把局部變量改變為靜态變量後是改變了它的存儲方式即改變了它的生存期。把全局變量改變為靜态變量後是改變了它的作用域,限制了它的使用範圍。

static函數與普通函數作用域不同。僅在本文件。隻在當前源文件中使用的函數應該說明為内部函數(static),内部函數應該在當前源文件中說明和定義。對于可在當前源文件以外使用的函數,應該在一個頭文件中說明,要使用這些函數的源文件要包含這個頭文件。

static全局變量與普通的全局變量有什麼區别:static全局變量隻初使化一次,防止在其他文件單元中被引用。

static局部變量和普通局部變量有什麼區别:static局部變量隻被初始化一次,下一次依據上一次結果值。

static函數與普通函數有什麼區别:static函數在内存中隻有一份,普通函數在每個被調用中維持一份拷貝。

32 函數system()與exec()的區别

system()會調用shell,而exec()則不會調用shell。system是在單獨的進程中執行命令,執行完畢還會回到程序中;而exec()則直接在進程中執行新的程序,新的程序會把原程序覆蓋,除非調用出錯,否則再也回不到exec()函數後面的代碼。

system()會産生新的pid(生成新的shell),而exec()則不會。

33 緩沖輸入與緩沖區

緩沖輸入,将若幹内容先存儲到稱為緩沖區(buffer)的臨時存儲區域,等待适當時機将緩沖區内的内容變得對程序可用,非緩沖輸入是不使用緩沖區,直接讓輸入對程序可用。緩沖輸入對于頻繁讀寫有更高的效率,而非緩沖輸入是即時交互程序所需要的。

34 位操作

在C語言中,可以單獨操控變量中的位。讀者可能好奇,竟然有人想這樣做。有時必須單獨操控位,而且非常有用。例如,通常向硬件設備發送一兩個字節來控制這些設備,其中的每個位(bit)都有特定的含義。另外,與文件相關的操作信息經常被儲存,通過使用特定位表明特定項。許多壓縮和加密操作都是直接處理單獨的位。高級語言一般不會處理這些級别的細節,C在提供高級語言使得的同時,還能在為彙編語言所保留的級别上工作,這使其成為編寫設備驅動程序和嵌入式代碼的首選語言。

在實際的程序設計中,有時需要存儲少量的信息,這些信息并不需要占用一個完整的字節,隻需占用幾個或一個二進制位。例如,在存入一個标志時,隻有0和1兩種狀态,用一個二進制即可。如果給其分配一個字節的空間,便浪費了存儲空間。因此,C 引入了位域這一數據類型。

35 為什麼0.1 0.2 != 0.3

浮點數雖然可以表示很大的數,是因為其分為小數位和指數位兩部分,小數位其實也就是有限的六、七位。

實數在内存中戰占4個字節,是按照指數形式存儲的,實型數據分為小數部分和指數部分:

I 小數部分:用二進制表示。

I 指數部分:用2的幂次來表示;

二進制的0.111等于十進制的多少?

c語言必背入門代碼解釋(小白入門C語言20問20答2)3

十進制的0.1表示為二進制:0.0001 1001 1001 1001…(無限循環)

十進制的0.2表示為二進制:0.0011 0011 0011 0011…(無限循環)

雙精度浮點數的小數部分最多支持 52 位,所以兩者相加之後得到這麼一串 :

0.0100110011001100110011001100110011001100110011001100

因浮點數小數位的限制而截斷的二進制數字,這時候,我們再把它轉換為十進制,就成了 :

0.30000000000000004。

二進制表示小數的特殊性,以及位數的限制,所以十進制的小數表示成二進制時,誤差始終會存在。

如以下實例:

#include<stdio.h> #include<stdlib.h> int main() { if(0.1 0.2 == 0.3) printf("0.1 0.2 = 0.3"); else printf("0.1 0.2 = %f",0.1 .3); system("pause"); } //output:0.1 0.2 = 0.400000

36 地址、标識符、指針

CPU 訪問内存時需要的是地址,而不是變量名和函數名!變量名和函數名隻是地址的一種助記符,當源文件被編譯和鍊接成可執行程序後,它們都會被替換成地址。編譯和鍊接過程的一項重要任務就是找到這些名稱所對應的地址。

然而指針也是一種變量,他裡面裝的就是所指數據或者代碼的地址。所以它可以指變量,也可以指函數。

37 函數調用

函數調用有三種形式:

I 把函數調用作為一條語句;

II 函數調用出現在一個表達式中;

III 函數調用作為一個函數的實際參數;

函數被調用時,系統為每個形參分配内存單元,也就是相當于一個局部變量的聲明後的初始化。

函數可以通過函數指針被調用(也是以上三種調用形式)。函數指針還可以用作函數參數或函數返回值。

38 指針數組與數組指針

int *p1[10]; //指針數組

int (*p2)[10]; //數組指針

“[]”的優先級比“*”要高(即使優先級相同,而它們的結合性是從右至左)。p1 先與“[]”結合,構成一個數組的定義,數組名為p1,int *修飾的是數組的内容,即數組的每個元素。那現在我們清楚,這是一個數組,其包含10 個指向int 類型數據的指針,即指針數組。至于p2 就更好理解了,在這裡“()”的優先級比“[]”高,“*”号和p2 構成一個指針的定義,指針變量名為p2,int 修飾的是數組的内容,即數組的每個元素。數組在這裡并沒有名字,是個匿名數組。那現在我們清楚p2 是一個指針,它指向一個包含10 個int 類型數據的數組,即數組指針。

如何簡單記憶呢?

沒有括号,重心落在右邊,符号*[],即指針數組,一個包括指針變量元素的數組。

如果有括号,重心落在括号,符号(*)[],即數組指針,一個指向數組的指針。

函數指針與指針函數也是如此理解:

int *f1(10); //指針函數

int (*f2)(10); //函數指針

39 數組做為參數時退化為指針的性能優勢

數組作為函數參數時,在函數調用時,并不需要另行開辟内存空間,也就不需要另行對參數進行初始化或賦值,這是既節省了空間,也節省了時間。當然,指針傳遞可修改數組,如果想保護數組不被修改,隻被訪問,可以使用const作為數組參數前綴。

數組引用“退化”為指針的規則隻适用于數組,而結構卻是一級對象,當你提到結構的時候,你得到的是整個結構。

40 語句執行順序的順序執行與跳轉執行

控制結構的四類語句有順序、條件、循環、跳轉(continue,break,goto,return),條件和循環的結構其實也就相當于順序加跳轉的結構。

按存儲程序和程序控制的概念,控制器的程序計數器确定指令的讀取位置,通常是順序讀取,但也可以跳轉地址讀取不同的指令。而高級語言的條件、循環語句的控制結構的實質就是跳轉讀取指令,類似于彙編語言的jmp和Basic語言的goto。

在C和C 語言中,也有goto語句,且能與條件、循環語句實現相同的效果,但後者顯然更為優勢。

goto也并不是豪無優勢,它可以跳出多重循環。(break隻能跳出單重循環)

-End-

,

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关生活资讯推荐

热门生活资讯推荐

网友关注

Copyright 2023-2024 - www.tftnews.com All Rights Reserved