[c 要點(diǎn)回顧]《C 程序設(shè)計新思維》 第6 - 8 章筆記

[c 要點(diǎn)回顧]《C 程序設(shè)計新思維》 第6 - 8 章筆記

首先,這本書還是蠻值得一看的,然后呢,前六章是一些有用的工具的介紹。

第 6 章 玩轉(zhuǎn)指針

6. 1 自動,靜態(tài) 和手工內(nèi)存

C 提供三種內(nèi)存管理的模式,理解這三種概念,對于我們理解變量,尋找類似核心已轉(zhuǎn)移的bug有莫大的幫助。

自動

當(dāng)我們聲明一個變量后,當(dāng)程序離開他的作用域后,就會被程序銷毀

靜態(tài)

函數(shù)外部聲明的(文件作用域) 和 函數(shù)內(nèi)部使用static 聲明的都是靜態(tài)的,他們會在整個程序生命周期內(nèi)存在。且如果沒有初始化,默認(rèn)為0(NULL)

所以我們可以看出,靜態(tài)變量也是一種自動管理的模式,只不過作用域是文件作用域。

手動

即,malloc free ,也是唯一一種,在聲明之后改變數(shù)組長度的方式(使用 realloc() )

注意,這也是手動申請的數(shù)組無法使用sizeof來測量大小的原因

補(bǔ)充一下:

堆棧和棧:

任何函數(shù)都在內(nèi)存中占據(jù)一個空間,稱為函數(shù)幀,用以保存,與這個函數(shù)相關(guān)的信息,

例如,一個函數(shù)執(zhí)行后返回到哪里,以及保存所有自動分配的變量的空間

當(dāng)一個函數(shù)調(diào)用另一個函數(shù)的時候,第一個函數(shù)的函數(shù)幀中的活動就會暫停,并且一個心得函數(shù)被添加到這個函數(shù)幀中去,當(dāng)函數(shù)執(zhí)行完畢后,它的函數(shù)幀就會彈出,所有保存在這個函數(shù)幀的所有變量都會消失,這就是自動的變量管理的方式

注意的是這個堆棧的大小一般為2~3M 所以,當(dāng)需要更多的更加自由的管理方式的時候,我們就調(diào)用malloc ,從堆中要一塊內(nèi)存,歸自己管理,而這個堆就是內(nèi)存的大小。這也是及時使用free的重要性。

這是使用static 實(shí)現(xiàn)斐波那契數(shù)列的一個方式

/*************************************************************************
    > File Name: staticTest.c
    > Author:Gin.TaMa 
    > Mail:1137554811@qq.com 
    > Created Time: 2019年03月20日 星期三 14時42分53秒
 ************************************************************************/

#include<stdio.h>
long long int fib(){
    static long long int first = 0;
    static long long int second = 1;
    long long int out = first + second;
    first = second;
    second = out;
    return out;
}
int main(){
    for(int i = 0;i < 10;i ++){
        printf("%lld\n",fib());
    }
    return 0;
}

以及一個有意思的bug

/*************************************************************************
    > File Name: staticBug.c
    > Author:Gin.TaMa 
    > Mail:1137554811@qq.com 
    > Created Time: 2019年03月20日 星期三 14時46分40秒
 ************************************************************************/

#include<stdio.h>

char* aToA(char a){
    static char A;
    A = a + 'A' - 'a';
    return &A;
}

void test(char* a){
    printf("a = %c\n",*a);
    // 沒有改變a的注意
    char* b = aToA('b');
    printf("a = %c ; b = %c\n",*a,*b);
    // a的值改變了
}

int main(){
    char* a = aToA('a');
    printf("a = %c\n",*a);
    test(a);
    return 0;
}

猜一下結(jié)果是不是這樣的呢?

a = A
a = A
a = B ; b = B

這個bug一開始找了我半天。。

關(guān)鍵是我是調(diào)用別實(shí)現(xiàn)的aToA()這樣類似的函數(shù)。

這其實(shí)是叫做別名和賦值的區(qū)別

當(dāng)我們告訴計算機(jī)把a(bǔ)設(shè)置成b的時候有兩種意義

別名,賦值。

a 為 b的別名:意味著,修改a,就是在修改b。

a 為b的賦值: 意味著a與b僅是有相同的值,但是沒有半毛錢的關(guān)系。

這里就要注意了,

結(jié)構(gòu)被復(fù)制,數(shù)組創(chuàng)建別名

當(dāng)一個結(jié)構(gòu)體b里有一個數(shù)組的時候,

你想將b的值賦值給a,很有可能,a的數(shù)組是b的數(shù)組的別名,也就意味著,你修改了a的數(shù)組元素,就是在修改b的數(shù)組

* 的解釋

關(guān)于* 其實(shí)是一個不好的設(shè)計,它把兩種情況雜糅到了一起,需要你依據(jù)上下文判斷他的意思。

它違背了所謂的“功能截然不同的事務(wù),看上去應(yīng)該明顯不一樣”

注意 * 在聲明中,代表指針。在其他地方代表取指針指向的內(nèi)容。

所以

int* i = 3; // WRONG
int* i = malloc(sizeof(int)); // OK
    *i = 3; // OK

記住這個就OK了。

第?。贰≌?,沒啥意思。

第8 章

8.1 營造健壯和繁榮的宏

==宏的本質(zhì)是一種沒有腦子的文本替換==

  • ()括號,一定要加

  • {}也要加

  • 避免重復(fù)作用

    #define max(a,b)  (((a) > (b)) ? (a) : (b))
    

    這個是有隱患的比如 max(i ++ ,x ) i 會被加兩次。。

補(bǔ)充

_VA_ARG_ 這是變參宏獲得變量的關(guān)鍵字

變參宏的一種用法。。

define printf_debug(format,...) printf(__FILE__"(%s:%d)"format"", __FUNCTION__, __LINE__, ##__VA_ARGS__)

8.3 const 關(guān)鍵字

注意 ==const 是一種文法,而不是一種鎖==

理解const的關(guān)鍵是從右向左閱讀,并且注意,const作用于const左邊的文本就像* 一樣。

int const  = 一個(不變的)整數(shù)常量
int const * = 指向一個(不變的)整數(shù)常量的(可以變的)變量指針
int * const = 指向一個(可以變的)變量整數(shù) 的(不變的)常亮指針

注意 常量結(jié)構(gòu)的成員并不是常量。
OK 不。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容