新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > C語言程序內存分配

        C語言程序內存分配

        作者: 時間:2016-11-27 來源:網絡 收藏

        (1) & 與 * 操作

        取地址運算符 &: p = &c;

        --表達式解析: 將 c 的地址賦值給 變量 p, p 是指向 c 變量的指針;

        --& 可以使用的情況: 取地址操作 只能用于內存中的對象, 如變量 或 數組, 棧內存 堆內存 都可以;

        --& 不適用的情況: 不能用于 表達式, 常量, register類型變量;

        間接引用運算符: * ;

        --聲明指針: int *p ; 該表達式的含義是*p 的結果是 int 類型, 聲明變量 a, int a, 聲明指針 *p , int *p;

        --獲取指針指向的值: int a = *p ;

        (2) 指針定義解析

        聲明指針 和 函數: int *p, max(int a, int b), 聲明指針變量 語法 與聲明 變量語法類似, 同理聲明函數也一樣;

        --原理: *p 和 max()返回值 類型都是 int 類型;

        指針指向: 每個指針都必須指向某種特定類型;

        --例外: void *p 可以指向任何類型, 但是 p 不能進行取值運算, *p 是錯誤的, 因為不知道 p 指向的數據類型;

        (3) 指針運算及示例

        指針相關運算: int x = 0; int *p = &x; 那么*p 就可以代表x;

        --算數運算: x = x + 1; 等價于 *p = *p + 1 ; int y = x + 1; 等價于 int y = *p + 1;

        --自增運算: 前提 : ++, * 運算順序是自右向左; ++*p 和 (*p)++, p 指向的值自增1, 注意要加上括號, 否則會將地址自增;

        --指針賦值: int *p, *q; int a = 0; p = &a; q = p; 最終結果 p 和 q 都指向了 變量 a;

        示例程序:

        [cpp]view plaincopy
        1. /*************************************************************************
        2. >FileName:pointer_address.c
        3. >Author:octopus
        4. >Mail:octopus_work.163.com
        5. >CreatedTime:Mon10Mar201409:52:01PMCST
        6. ************************************************************************/
        7. #include
        8. intmain(intargc,char**argv)
        9. {
        10. int*p,*q;
        11. inta=10,b;
        12. //p指針指向a變量
        13. p=&a;
        14. //*p可以代替a進行運算
        15. ++*p;
        16. b=*p+5;
        17. //指針之間可以直接相互賦值
        18. q=p;
        19. //打印p和q指針指向的值
        20. printf("*p=%d",*p);
        21. printf("*q=%d",*q);
        22. return0;
        23. }


        執行結果:

        [cpp]view plaincopy
        1. [root@ip28pointer]#gccpointer_address.c
        2. [root@ip28pointer]#./a.out
        3. *p=11
        4. *q=11

        4. 函數參數的傳值調用和傳址調用

        (1) 傳值調用 和 傳址調用

        傳值調用: 以傳值的方式將參數傳遞給函數, 不能直接修改主函數中變量的值, 僅僅是將副本傳遞給了函數;

        傳址調用: 將 變量的指針 傳遞給函數, 當函數對指針進行操作的時候, 主函數中的值也進行了對應變化;

        交換函數示例1:

        [cpp]view plaincopy
        1. /*************************************************************************
        2. >FileName:swap.c
        3. >Author:octopus
        4. >Mail:octopus_work.163.com
        5. >CreatedTime:Mon10Mar201411:07:18PMCST
        6. ************************************************************************/
        7. #include
        8. voidswap_1(inta,intb)
        9. {
        10. inttemp;
        11. temp=a;
        12. a=b;
        13. b=temp;
        14. printf("swap_1傳值函數a=%d,b=%d",a,b);
        15. }
        16. voidswap_2(int*a,int*b)
        17. {
        18. inttemp;
        19. temp=*a;
        20. *a=*b;
        21. *b=temp;
        22. printf("swap_2傳址函數a=%d,b=%d",*a,*b);
        23. }
        24. intmain(intargc,char**argv)
        25. {
        26. inta=10,b=5;
        27. printf("初始值:a=%d,b=%d",a,b);
        28. swap_1(a,b);
        29. printf("執行swap_1函數,a=%d,b=%d",a,b);
        30. swap_2(&a,&b);
        31. printf("執行swap_2函數,a=%d,b=%d",a,b);
        32. return0;
        33. }


        執行結果:

        [cpp]view plaincopy
        1. [root@ip28pointer]#gccswap.c
        2. [root@ip28pointer]#./a.out
        3. 初始值:a=10,b=5
        4. swap_1傳值函數a=5,b=10
        5. 執行swap_1函數,a=10,b=5
        6. swap_2傳址函數a=5,b=10
        7. 執行swap_2函數,a=5,b=10



        示例解析:

        --傳值調用: swap_1 是傳值調用, 傳入的是 main 函數中的 a b 兩個變量的副本, 因此函數執行完畢后, 主函數中的值是不變的;

        --傳址調用: swap_2 是傳址調用, 傳入的是 a , b 兩個變量的地址 &a, &b, 當在swap_2 中進行修改的時候, 主函數中的 a,b變量也會發生改變;

        (2) 高級示例

        需求分析: 調用getint()函數, 將輸入的數字字符 轉為一個整形數據;

        getch 和 ungetch 函數:

        --使用場景: 當進行輸入的時候, 不能確定是否已經輸入足夠的字符, 需要讀取下一個字符, 進行判斷, 如果多讀取了一個字符, 就需要將這個字符退回去;

        --使用效果: getch() 和 ungetch() 分別是預讀下一個字符, 和 將預讀的字符退回去, 這樣對于其它代碼而言, 沒有任何影響;

        注意的問題 : 出現問題, 暫時編譯不通過, 找個C語言大神解決;

        代碼:

        [cpp]view plaincopy
        1. /*************************************************************************
        2. >FileName:getint.c
        3. >Author:octopus
        4. >Mail:octopus_work.163.com
        5. >CreatedTime:Mon10Mar201411:40:19PMCST
        6. ************************************************************************/
        7. #include
        8. #include
        9. #include
        10. #defineSIZE5
        11. intgetint(int*p)
        12. {
        13. //sign是用來控制數字的正負
        14. intc,sign;
        15. //跳過空白字符,如果是空白字符,就會進行下一次循環,直到不是空白字符為止
        16. while(isspace(c=getc(stdin)));
        17. //如果輸入的字符不是數字,就將預讀的數據退回到標準輸入流中
        18. if(!isdigit(c)&&c!=EOF&&c!=+&&c!=-)
        19. {
        20. ungetc(c,stdin);
        21. return0;
        22. }
        23. /*
        24. *如果預讀的是減號,那么sign標識就是-1,
        25. *如果預讀的是加號,那么sign標識就是1;
        26. */
        27. sign=(c==-)?-1:1;
        28. //如果c是加號或者減號,再預讀一個字符&
        29. if(c==+||c==-)
        30. c=getc(stdin);
        31. for(*p=0;isdigit(c);c=getc(stdin))
        32. *p=10**p+(c-0);
        33. *p*=sign;
        34. if(c!=EOF)
        35. ungetc(c,stdin);
        36. returnc;
        37. }
        38. intmain(intargc,char**argv)
        39. {
        40. intn,array[SIZE],i;
        41. for(n=0;n
        42. for(i=0;i
        43. {
        44. printf("array[%d]=%d",i,array[i]);
        45. }
        46. return0;
        47. }

        執行結果:

        [plain]view plaincopy
        1. octopus@octopus-Vostro-270s:~/code/c/pointer$./a.out
        2. 123
        3. 12343
        4. 6741
        5. array[0]=123
        6. array[1]=123
        7. array[2]=43
        8. array[3]=674
        9. array[4]=1

        5. 指針 和 數組

        指針數組比較:

        --可互相替代: 數組下標執行的操作都可以使用指針替代;

        --效率比較: 使用指針操作效率比數組要高;

        指針 與 數組初始化:

        --聲明數組: int a[10]; 定義一個長度為10 的int數組;

        --聲明指針: int *p; 定義一個指針, 該指針指向整型;

        --相互賦值: p = &a[0], 將數組第一個元素的地址賦值給指針變量;

        --使用指針獲取數組對象: *p 等價于 a[0], *(p + 1) 等價于 a[1], *(p + i)等價于 a[i];

        --注意地址的運算: p + i , 在地址運算上, 每次增加 sizeof(int) * i 個字節;

        將數組賦值給指針的途徑:

        --將數組第一個元素地址賦值給指針變量: p = &a[0];

        --將數組地址賦值給指針變量: p = a;

        指針 和 數組 訪問方式互換: 前提 int *p, a[10]; p = a;

        --數組計算方式: 計算a[i]的時候, 先將數組轉化為 *(a + i)指針, 然后計算該指針值;

        --取值等價: a[i] 等價于 *(p + i);

        --地址等價: &a[i] 與 a + i 是等價的;

        --指針下標訪問: p[i] 等價于 *(p + i);

        --結論: 通過數組和下標實現的操作 都可以使用指針和偏移量進行等價替換;

        指針 和 數組 的不同點:

        --指針是變量: int *p, a[10]; p = a 和 p++ 沒有錯誤;

        --數組名不是變量: int *p, a[10]; a = p 和 a++ 會報錯;

        數組參數:

        --形參指針: 將數組傳作為參數傳遞給函數的時候, 傳遞的是數組的首地址, 傳遞地址, 形參是指針;

        數組參數示例:

        --函數參數是數組: 函數傳入一個字符串數組參數, 返回這個字符串長度;

        [cpp]view plaincopy
        1. /*************************************************************************
        2. >FileName:array_param.c
        3. >Author:octopus
        4. >Mail:octopus_work.163.com
        5. >CreatedTime:Sat15Mar201412:46:57AMCST
        6. ************************************************************************/
        7. #include
        8. //計算字符串長度
        9. intstrlen(char*s)
        10. {
        11. intn;
        12. for(n=0;*s!= 主站蜘蛛池模板: 武城县| 固安县| 庆阳市| 台江县| 泽库县| 邓州市| 额尔古纳市| 什邡市| 钦州市| 锡林郭勒盟| 汉中市| 望奎县| 三原县| 股票| 天门市| 元谋县| 东港市| 名山县| 自治县| 彩票| 拜泉县| 新乡县| 盐亭县| 沐川县| 长沙市| 眉山市| 临邑县| 建湖县| 静乐县| 泽州县| 晋城| 大邑县| 江陵县| 卓资县| 河东区| 霍邱县| 桦甸市| 西乡县| 万州区| 喀喇沁旗| 株洲市|