<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

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

          C語言程序內存分配

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

          (1) & 與 * 操作

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

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

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

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

          間接引用運算符: * ;

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

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

          (2) 指針定義解析

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

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

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

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

          (3) 指針運算及示例

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

          --算數(shù)運算: 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. }


          執(zhí)行結果:

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

          4. 函數(shù)參數(shù)的傳值調用和傳址調用

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

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

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

          交換函數(shù)示例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傳值函數(shù)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傳址函數(shù)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("執(zhí)行swap_1函數(shù),a=%d,b=%d",a,b);
          30. swap_2(&a,&b);
          31. printf("執(zhí)行swap_2函數(shù),a=%d,b=%d",a,b);
          32. return0;
          33. }


          執(zhí)行結果:

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



          示例解析:

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

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

          (2) 高級示例

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

          getch 和 ungetch 函數(shù):

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

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

          注意的問題 : 出現(xiàn)問題, 暫時編譯不通過, 找個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是用來控制數(shù)字的正負
          14. intc,sign;
          15. //跳過空白字符,如果是空白字符,就會進行下一次循環(huán),直到不是空白字符為止
          16. while(isspace(c=getc(stdin)));
          17. //如果輸入的字符不是數(shù)字,就將預讀的數(shù)據(jù)退回到標準輸入流中
          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. }

          執(zhí)行結果:

          [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. 指針 和 數(shù)組

          指針數(shù)組比較:

          --可互相替代: 數(shù)組下標執(zhí)行的操作都可以使用指針替代;

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

          指針 與 數(shù)組初始化:

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

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

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

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

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

          將數(shù)組賦值給指針的途徑:

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

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

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

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

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

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

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

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

          指針 和 數(shù)組 的不同點:

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

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

          數(shù)組參數(shù):

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

          數(shù)組參數(shù)示例:

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

          [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!=看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();