<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 牛人業(yè)話(huà) > C語(yǔ)言的那些小秘密之變參函數的實(shí)現

C語(yǔ)言的那些小秘密之變參函數的實(shí)現

作者: 時(shí)間:2015-03-06 來(lái)源:網(wǎng)絡(luò ) 收藏

  其中有幾條指令在此講解下。

本文引用地址:http://dyxdggzs.com/article/270588.htm

  leave指令所做的操作相當于如下兩條指令:

  movl %ebp, %esp

  popl %ebp

  ret指令所做的操作相當于如下指令:

  pop %eip

  如果有對AT&T匯編語(yǔ)法規則不懂的,可以看看我前面寫(xiě)的那篇文章。

  到這兒為止是乎應該是說(shuō)結束的時(shí)候了,但是細心的讀者可能發(fā)現了一個(gè)問(wèn)題,就是我們在最初給出的代碼部分有一句紅色標記的代碼,如下:

  #define va_start(arg, start) arg = (va_list)(((char*)&(start)) + sizeof(start))

  為什么要把這句代碼單獨拿出來(lái)講解呢,肯定是有原因的,因為((char*)&(start)) +sizeof(start)這句代碼的特殊性在于使用了(char*)進(jìn)行強制轉換,在這里為什么不使用(int*)進(jìn)行強制轉換呢,如改為如下代碼:

  #include

  #include

  #define va_list void*

  #define va_arg(arg, type) *(type*)arg; arg = (char*)arg + sizeof(type);

  #define va_start(arg, start) arg = (va_list)(((int*)&(start)) + sizeof(start)) //修改為(int*)

  int sum(int nr, ...)

  {

  int i = 0;

  int result = 0;

  va_list arg = NULL;

  va_start(arg, nr);

  for(i = 0; i < nr; i++)

  {

  result += va_arg(arg, int);

  }

  return result;

  }

  int main(int argc, char* argv[])

  {

  printf("%dn", sum(4, 100,100,100,100));

  printf("%dn", sum(3, 200, 200, 200));

  return 0;

  }

  運行結果為:



  顯然運行結果是錯誤的,為什么會(huì )出現這樣的錯誤呢,我們暫且不分析,先來(lái)看看我們接下來(lái)做的修改:

  #include

  #include

  #define va_list void*

  #define va_arg(arg, type) *(type*)arg; arg = (char*)arg + sizeof(type);

  #define va_start(arg, start) arg = (va_list)(((int*)&(start)) + sizeof(start)/4) //注意對比紅色部分的變化

  int sum(int nr, ...)

  {

  int i = 0;

  int result = 0;

  va_list arg = NULL;

  va_start(arg, nr);

  for(i = 0; i < nr; i++)

  {

  result += va_arg(arg, int);

  }

  return result;

  }

  int main(int argc, char* argv[])

  {

  printf("%dn", sum(4, 100,100,100,100));

  printf("%dn", sum(3, 200, 200, 200));

  return 0;

  }

  運行結果如下:



  運行結果正確。

  現在來(lái)分析下為什么會(huì )出現這兩種結果呢,看看下面我給出的這個(gè)圖解和代碼應該就能夠很清楚的理解為什么會(huì )出現以上的兩種運行結果了。



  代碼如下:

  #include

  int main()

  {

  int a = 12;

  int *p_int = &a;

  char *p_char = (char*)&a;

  printf( "%d t", sizeof(char));

  printf( "%d t", sizeof(int));

  printf( "%d t", p_int+1);

  printf( "%d t", p_char+1);

  return 0;

  }

  運行結果為:



  修改以上紅色部分的代碼,得到如下代碼:

  #include

  int main()

  {

  int a = 12;

  int *p_int = &a;

  char *p_char = (char*)&a;

  printf( "%d t", sizeof(char));

  printf( "%d t", sizeof(int));

  printf( "%d t", p_int+1);

  printf( "%d t", p_char+4);

  return 0;

  }

  注意對比前后代碼的變化部分!!!

  運行結果如下:



  首先看看給出的圖,int指針所指向的單元占有四個(gè)字節的空間,而char指針所指向的單元只占有一個(gè)字節的空間。所以如果是整形指針想要取下一個(gè)參數,只需加1,但是如果是char指針,如果當前參數是int型,那么想要取下一個(gè)參數就要加4才能實(shí)現。但是值得注意的是,int*和char*所占的存儲單元都是4個(gè)字節,這是由我們所使用的32位計算機本身確定的。為了加深大家的印象,特地給出如下代碼:

  #include

  int main()

  {

  int a = 12;

  int *p_int = &a;

  char *p_char = (char*)&a;

  printf( "%d t", sizeof(char*));

  printf( "%d t", sizeof(int*));

  return 0;

  }

  運行結果如下:



  到此為止就是真的該結束了,總不能沒(méi)完沒(méi)了的講下去吧,呵呵……

  很多代碼僅僅是修改了一點(diǎn),我都貼出了完整的代碼,是希望你在閱讀的過(guò)程中能直接copy過(guò)去,看看運行效果,加深下印象。還是那句話(huà),C語(yǔ)言博大精深,我還是C語(yǔ)言菜鳥(niǎo),以上內容難免有錯。

樹(shù)莓派文章專(zhuān)題:樹(shù)莓派是什么?你不知道樹(shù)莓派的知識和應用

c語(yǔ)言相關(guān)文章:c語(yǔ)言教程



上一頁(yè) 1 2 下一頁(yè)

關(guān)鍵詞: C語(yǔ)言 函數

評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>