亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫(kù)
12下一頁
最近訪問板塊 發(fā)新帖
查看: 4516 | 回復(fù): 16
打印 上一主題 下一主題

[C] c語言函數(shù)形參的地址關(guān)系 [復(fù)制鏈接]

論壇徽章:
6
摩羯座
日期:2013-08-24 10:43:10獅子座
日期:2013-08-25 10:27:06天秤座
日期:2013-09-11 20:28:44午馬
日期:2014-09-28 16:06:0015-16賽季CBA聯(lián)賽之八一
日期:2016-12-19 13:55:0515-16賽季CBA聯(lián)賽之天津
日期:2016-12-20 14:01:23
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2015-01-03 10:34 |只看該作者 |倒序?yàn)g覽
本帖最后由 cao627 于 2015-01-03 10:40 編輯
  1. include <stdio.h>

  2. void test1(int a,int b, int c)
  3. {
  4.         int * p;
  5.         p = &a;
  6.         printf("%d\n", *p);
  7.         p--;
  8.         printf("%d\n", *p);
  9.         p--;
  10.         printf("%d\n", *p);
  11. }

  12. void test2(const char * s, ...)
  13. {
  14.         int * p;
  15.         p = (int *)&s;
  16.         p++;
  17.         printf("%d\n", *p);
  18.         p++;
  19.         printf("%d\n", *p);
  20. }

  21. int main()
  22. {

  23.         test1(100,200,300);
  24.         test2("hello world",100,200);
  25.         return 0;
  26. }

復(fù)制代碼
看到一個(gè)視頻教程,里面用test2實(shí)現(xiàn)了:打印第二個(gè)參數(shù)和第三個(gè)參數(shù)的值,依據(jù)是形參的地址在內(nèi)存里緊挨著的,但在我的環(huán)境里無法實(shí)現(xiàn)這一點(diǎn)。

問題:
1.在test2中定義的是指向正整型指針p,對(duì)p++,p的步進(jìn)是4,而傳給test2的實(shí)參"hello world" 長(zhǎng)度大于4個(gè)字節(jié),p++后指向的應(yīng)該還是在"hello.world"  這串字符存儲(chǔ)的空間內(nèi),怎么能指到參數(shù)100的存儲(chǔ)空間,視頻教程里確實(shí)做到了。

2.在我的環(huán)境里test1的參數(shù)的地址關(guān)系是從左往右遞減的,即如上代碼是用p--實(shí)現(xiàn)依次打印第一,第二,第三個(gè)參數(shù)。而在視頻教程中是用p++。這跟編譯器不同的關(guān)系嗎?

論壇徽章:
6
酉雞
日期:2013-11-04 15:30:02巳蛇
日期:2014-01-23 10:36:23雙魚座
日期:2014-01-23 13:08:332015亞冠之鹿島鹿角
日期:2015-09-03 14:36:002015亞冠之武里南聯(lián)
日期:2015-09-18 10:48:1315-16賽季CBA聯(lián)賽之山西
日期:2016-05-05 00:05:33
2 [報(bào)告]
發(fā)表于 2015-01-03 17:48 |只看該作者
  1. #include<stdio.h>

  2. void test1(int a,int b, int c)
  3. {
  4.         int * p;
  5.         p = &a;
  6.         printf("%d\n", *p);
  7.         p++;
  8.         printf("%d\n", *p);
  9.         p++;
  10.         printf("%d\n", *p);
  11. }

  12. void test2(const char * s, ...)
  13. {
  14.         int * p;
  15.         p = (int *)&s;
  16.         p++;
  17.         printf("%d\n", *p);
  18.         p++;
  19.         printf("%d\n", *p);
  20. }

  21. int main()
  22. {
  23.         test1(100,200,300);

  24.         test2("hello world",100,200);

  25.         return 0;
  26. }
復(fù)制代碼
  1. ./a.out
  2. 100
  3. 200
  4. 300
  5. 100
  6. 200
復(fù)制代碼

論壇徽章:
6
酉雞
日期:2013-11-04 15:30:02巳蛇
日期:2014-01-23 10:36:23雙魚座
日期:2014-01-23 13:08:332015亞冠之鹿島鹿角
日期:2015-09-03 14:36:002015亞冠之武里南聯(lián)
日期:2015-09-18 10:48:1315-16賽季CBA聯(lián)賽之山西
日期:2016-05-05 00:05:33
3 [報(bào)告]
發(fā)表于 2015-01-03 17:51 |只看該作者
test2反匯編
  1. 080483f9 <test2>:
  2. 80483f9:       55                      push   %ebp
  3. 80483fa:       89 e5                   mov    %esp,%ebp
  4. 80483fc:       83 ec 18                sub    $0x18,%esp
  5. 80483ff:       8d 45 08                lea    0x8(%ebp),%eax
  6. 8048402:       89 45 fc                mov    %eax,0xfffffffc(%ebp)
  7. 8048405:       83 45 fc 04             addl   $0x4,0xfffffffc(%ebp)
  8. 8048409:       8b 45 fc                mov    0xfffffffc(%ebp),%eax
  9. 804840c:       8b 00                   mov    (%eax),%eax
  10. 804840e:       89 44 24 04             mov    %eax,0x4(%esp)
  11. 8048412:       c7 04 24 60 85 04 08    movl   $0x8048560,(%esp)
  12. 8048419:       e8 9a fe ff ff          call   80482b8 <printf@plt>
  13. 804841e:       83 45 fc 04             addl   $0x4,0xfffffffc(%ebp)
  14. 8048422:       8b 45 fc                mov    0xfffffffc(%ebp),%eax
  15. 8048425:       8b 00                   mov    (%eax),%eax
  16. 8048427:       89 44 24 04             mov    %eax,0x4(%esp)
  17. 804842b:       c7 04 24 60 85 04 08    movl   $0x8048560,(%esp)
  18. 8048432:       e8 81 fe ff ff          call   80482b8 <printf@plt>
  19. 8048437:       c9                      leave  
  20. 8048438:       c3                      ret   
復(fù)制代碼
  1. 8048405:       83 45 fc 04             addl   $0x4,0xfffffffc(%ebp)
復(fù)制代碼
這句對(duì)應(yīng)的是p++,其實(shí)是在棧上向移動(dòng)到了下一個(gè)地址

論壇徽章:
6
摩羯座
日期:2013-08-24 10:43:10獅子座
日期:2013-08-25 10:27:06天秤座
日期:2013-09-11 20:28:44午馬
日期:2014-09-28 16:06:0015-16賽季CBA聯(lián)賽之八一
日期:2016-12-19 13:55:0515-16賽季CBA聯(lián)賽之天津
日期:2016-12-20 14:01:23
4 [報(bào)告]
發(fā)表于 2015-01-03 19:45 |只看該作者
對(duì)于test1這樣的形式,在我的環(huán)境中要用指針遞減的方式才能依次打印各個(gè)參數(shù)。
對(duì)于test2這樣的形式,在我的環(huán)境中無論用指針遞增還是遞減都不能打印字符串長(zhǎng)量后的各個(gè)參數(shù)。

我的環(huán)境是
ubuntu 14.04  64位
gcc 4.8.2

論壇徽章:
6
摩羯座
日期:2013-08-24 10:43:10獅子座
日期:2013-08-25 10:27:06天秤座
日期:2013-09-11 20:28:44午馬
日期:2014-09-28 16:06:0015-16賽季CBA聯(lián)賽之八一
日期:2016-12-19 13:55:0515-16賽季CBA聯(lián)賽之天津
日期:2016-12-20 14:01:23
5 [報(bào)告]
發(fā)表于 2015-01-03 19:53 |只看該作者
本帖最后由 cao627 于 2015-01-03 19:54 編輯

@Dannysd
請(qǐng)你在test2中打印一下p取到字符串常量首地址的地址,然后再打印一下p++后的地址?纯磧傻刂返牟睢

論壇徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52雙子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午馬
日期:2013-10-18 21:43:38
6 [報(bào)告]
發(fā)表于 2015-01-03 20:22 |只看該作者
研究這個(gè)意義不大,不具有可移植性

論壇徽章:
6
酉雞
日期:2013-11-04 15:30:02巳蛇
日期:2014-01-23 10:36:23雙魚座
日期:2014-01-23 13:08:332015亞冠之鹿島鹿角
日期:2015-09-03 14:36:002015亞冠之武里南聯(lián)
日期:2015-09-18 10:48:1315-16賽季CBA聯(lián)賽之山西
日期:2016-05-05 00:05:33
7 [報(bào)告]
發(fā)表于 2015-01-03 20:57 |只看該作者
本帖最后由 Dannysd 于 2015-01-03 20:58 編輯

我是32位環(huán)境,gcc version 4.1.2 Centos
可變參數(shù)這個(gè)沒弄懂。。。。
test1
  1. Breakpoint 1, test1 (a=100, b=200, c=300) at c.c:13
  2. 13              p = &a;
  3. (gdb) n
  4. 14              printf("%d\n", *p);
  5. (gdb) p a
  6. $8 = 100
  7. (gdb) p *p
  8. $9 = 100
  9. (gdb) p &a
  10. $10 = (int *) 0xbfffc310
  11. (gdb) p/x p
  12. $11 = 0xbfffc310
  13. (gdb) n
  14. 100
  15. 15              p++;
  16. (gdb) p *p
  17. $12 = 100
  18. (gdb) p/x p
  19. $13 = 0xbfffc310
  20. (gdb) n
  21. 16              printf("%d\n", *p);
  22. (gdb) p *p
  23. $14 = 200
  24. (gdb) p/x p
  25. $15 = 0xbfffc314
  26. (gdb) n
  27. 200
  28. 17              p++;
  29. (gdb) p *p
  30. $16 = 200
  31. (gdb) p/x p
  32. $17 = 0xbfffc314
  33. (gdb) n
  34. 18              printf("%d\n", *p);
  35. (gdb) p *p
  36. $18 = 300
  37. (gdb) p/x p
  38. $19 = 0xbfffc318
  39. (gdb) n
  40. 300
  41. 19      }
復(fù)制代碼
============================
test2
  1. Breakpoint 1, test2 (s=0x8048564 "hello world") at c.c:24
  2. 24              p = (int *)&s;
  3. (gdb) p *p
  4. $1 = 200
  5. (gdb) p/x p
  6. $2 = 0xbfffe588
  7. (gdb) n
  8. 25              p++;
  9. (gdb) p *p
  10. $3 = 134514020
  11. (gdb) p/x p
  12. $4 = 0xbfffe580
  13. (gdb) n
  14. 26              printf("%d\n", *p);
  15. (gdb) p *p
  16. $5 = 100
  17. (gdb) p/x p
  18. $6 = 0xbfffe584
  19. (gdb) n
  20. 100
  21. 27              p++;
  22. (gdb) p *p
  23. $7 = 100
  24. (gdb) p/x p
  25. $8 = 0xbfffe584
  26. (gdb) n
  27. 28              printf("%d\n", *p);
  28. (gdb) p *p
  29. $9 = 200
  30. (gdb) p/x p
  31. $10 = 0xbfffe588
  32. (gdb) n
  33. 200
  34. 29      }
  35. (gdb) p *p
  36. $11 = 200
  37. (gdb) p/x p
  38. $12 = 0xbfffe588
  39. (gdb) n
  40. main () at c.c:37
  41. 37              return 0;
  42. (gdb) n
  43. 38      }
  44. (gdb) n
  45. 0x00c44ebc in __libc_start_main () from /lib/libc.so.6
  46. (gdb) n
  47. Single stepping until exit from function __libc_start_main,
  48. which has no line number information.

  49. Program exited normally.
復(fù)制代碼

論壇徽章:
6
摩羯座
日期:2013-08-24 10:43:10獅子座
日期:2013-08-25 10:27:06天秤座
日期:2013-09-11 20:28:44午馬
日期:2014-09-28 16:06:0015-16賽季CBA聯(lián)賽之八一
日期:2016-12-19 13:55:0515-16賽季CBA聯(lián)賽之天津
日期:2016-12-20 14:01:23
8 [報(bào)告]
發(fā)表于 2015-01-03 22:17 |只看該作者
本帖最后由 cao627 于 2015-01-03 22:28 編輯
1.在test2中定義的是指向正整型指針p,對(duì)p++,p的步進(jìn)是4,而傳給test2的實(shí)參"hello world" 長(zhǎng)度大于4個(gè)字節(jié),p++后指向的應(yīng)該還是在"hello.world"  這串字符存儲(chǔ)的空間內(nèi),怎么能指到參數(shù)100的存儲(chǔ)空間,視頻教程里確實(shí)做到了。



("hello world",100,200) 在內(nèi)存棧中開辟的是   存放helllo world字符串的首地址的空間,4字節(jié)空間,4字節(jié)空間
p首先取得是存放helllo world字符串的首地址的空間的地址。
對(duì)p++后就取到了存放helllo world字符串的首地址的空間后面的4字節(jié)空間


對(duì)于32位系統(tǒng),地址的長(zhǎng)度是4字節(jié),上面的存放helllo world字符串的首地址的空間就是4字節(jié)。p是定義的是指向int型的,p++的步進(jìn)是4, 所以*(p++) 取得存放helllo world字符串的首地址的4字節(jié)空間的后面一個(gè)4字節(jié)的空間的內(nèi)容。

但是對(duì)于64位系統(tǒng),地址的長(zhǎng)度是8字節(jié),上面的存放helllo world字符串的首地址的空間就是8字節(jié)。p是定義的是指向int型的,p++的步進(jìn)是4,所以*(P++)不能取到存放helllo world字符串的首地址的8字節(jié)空間后面一個(gè)4字節(jié)空間的內(nèi)容。

這可能就是我的系統(tǒng)(64位)上形參地址是從左往又依次遞減的緣故?
這樣:存放helllo world字符串的首地址的8字節(jié)空間的地址高于緊挨它的形參括號(hào)中它右邊4字節(jié)空間的地址,設(shè)形參括號(hào)中它右邊4字節(jié)空間的地址是A,由于這塊空間的大小為4字節(jié),所以存放helllo world字符串的首地址的8字節(jié)空間的地址就是A+4。這樣p取到存放helllo world字符串的首地址的8字節(jié)空間的地址,*(p--)就正好取到形參括號(hào)中它右邊4字節(jié)空間內(nèi)容。

論壇徽章:
6
酉雞
日期:2013-11-04 15:30:02巳蛇
日期:2014-01-23 10:36:23雙魚座
日期:2014-01-23 13:08:332015亞冠之鹿島鹿角
日期:2015-09-03 14:36:002015亞冠之武里南聯(lián)
日期:2015-09-18 10:48:1315-16賽季CBA聯(lián)賽之山西
日期:2016-05-05 00:05:33
9 [報(bào)告]
發(fā)表于 2015-01-03 22:39 |只看該作者
回復(fù) 8# cao627


    默認(rèn)的是cdecl,從右至左壓參入棧

   要不加上 __attribute__((cdecl))這個(gè)再試試?

論壇徽章:
12
巳蛇
日期:2013-09-16 15:32:242015年辭舊歲徽章
日期:2015-03-03 16:54:152015年亞洲杯之約旦
日期:2015-02-11 14:38:37雙魚座
日期:2015-01-05 11:05:47戌狗
日期:2014-12-08 09:41:18戌狗
日期:2014-08-15 09:29:29雙子座
日期:2014-08-05 09:17:17卯兔
日期:2014-06-08 15:32:18巳蛇
日期:2014-01-27 08:47:08白羊座
日期:2013-11-28 21:04:15巨蟹座
日期:2013-11-13 21:58:012015年亞洲杯之科威特
日期:2015-04-17 16:51:51
10 [報(bào)告]
發(fā)表于 2015-01-04 09:45 |只看該作者
取決于ABI規(guī)范,函數(shù)調(diào)用約定屬于ABI規(guī)范的一部分。簡(jiǎn)單的說,現(xiàn)在還在用內(nèi)存?zhèn)鲄?shù)的,只有32位的x86了。
x86-64、arm這種都有完整的文檔,怎么傳參數(shù)查看文檔即可。

x86-64的附個(gè)鏈接:http://www.x86-64.org/documentation/abi.pdf
您需要登錄后才可以回帖 登錄 | 注冊(cè)

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專區(qū)
中國(guó)互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP