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

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > C語言程序內(nèi)存分配

          C語言程序內(nèi)存分配

          作者: 時(shí)間:2016-11-27 來源:網(wǎng)絡(luò) 收藏

          (1) & 與 * 操作

          取地址運(yùn)算符 &: p = &c;

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

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

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

          間接引用運(yùn)算符: * ;

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

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

          (2) 指針定義解析

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

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

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

          --例外: void *p 可以指向任何類型, 但是 p 不能進(jìn)行取值運(yùn)算, *p 是錯(cuò)誤的, 因?yàn)椴恢?p 指向的數(shù)據(jù)類型;

          (3) 指針運(yùn)算及示例

          指針相關(guān)運(yùn)算: int x = 0; int *p = &x; 那么*p 就可以代表x;

          --算數(shù)運(yùn)算: x = x + 1; 等價(jià)于 *p = *p + 1 ; int y = x + 1; 等價(jià)于 int y = *p + 1;

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

          --指針賦值: int *p, *q; int a = 0; p = &a; q = p; 最終結(jié)果 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進(jìn)行運(yùn)算
          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í)行結(jié)果:

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

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

          (1) 傳值調(diào)用 和 傳址調(diào)用

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

          傳址調(diào)用: 將 變量的指針 傳遞給函數(shù), 當(dāng)函數(shù)對指針進(jìn)行操作的時(shí)候, 主函數(shù)中的值也進(jìn)行了對應(yīng)變化;

          交換函數(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í)行結(jié)果:

          [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



          示例解析:

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

          --傳址調(diào)用: swap_2 是傳址調(diào)用, 傳入的是 a , b 兩個(gè)變量的地址 &a, &b, 當(dāng)在swap_2 中進(jìn)行修改的時(shí)候, 主函數(shù)中的 a,b變量也會(huì)發(fā)生改變;

          (2) 高級示例

          需求分析: 調(diào)用getint()函數(shù), 將輸入的數(shù)字字符 轉(zhuǎn)為一個(gè)整形數(shù)據(jù);

          getch 和 ungetch 函數(shù):

          --使用場景: 當(dāng)進(jìn)行輸入的時(shí)候, 不能確定是否已經(jīng)輸入足夠的字符, 需要讀取下一個(gè)字符, 進(jìn)行判斷, 如果多讀取了一個(gè)字符, 就需要將這個(gè)字符退回去;

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

          注意的問題 : 出現(xiàn)問題, 暫時(shí)編譯不通過, 找個(gè)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ù)字的正負(fù)
          14. intc,sign;
          15. //跳過空白字符,如果是空白字符,就會(huì)進(jìn)行下一次循環(huán),直到不是空白字符為止
          16. while(isspace(c=getc(stdin)));
          17. //如果輸入的字符不是數(shù)字,就將預(yù)讀的數(shù)據(jù)退回到標(biāo)準(zhǔn)輸入流中
          18. if(!isdigit(c)&&c!=EOF&&c!=+&&c!=-)
          19. {
          20. ungetc(c,stdin);
          21. return0;
          22. }
          23. /*
          24. *如果預(yù)讀的是減號,那么sign標(biāo)識就是-1,
          25. *如果預(yù)讀的是加號,那么sign標(biāo)識就是1;
          26. */
          27. sign=(c==-)?-1:1;
          28. //如果c是加號或者減號,再預(yù)讀一個(gè)字符&
          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í)行結(jié)果:

          [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ù)組下標(biāo)執(zhí)行的操作都可以使用指針替代;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

          [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. //計(jì)算字符串長度
          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); })();