1、函數形參的存儲
函數形參在函數中存儲是按照棧的方式來存儲的
實例:
#include <stdio.h>
void fun(int a0,int a1,int a2, int a3) { int *temp; temp=&a0; int i; for(i=0;i<4;i++){ printf("%d\t",*temp++); } } int main(){ fun(1,2,3,4); getchar(); return 0; }
函數輸出為:
1 2 3 4
2、一般函數的定義在內存中的存儲方式
一般的變量定義之后,相同的變量類型存儲在相鄰的一塊內存
例子:
#include <stdio.h>
int main() { int a0=1; char c0='a'; double d0=1.1; char c1='b'; double d1=2.2; int a1=2;
int a2=3; int *pint = &a0; char *pch = &c0; double *pd = &d0;
printf("%p:%d\n", pint, *pint); pint++; printf("%p:%d\n", pint, *pint); pint++; printf("%p:%d\t%p\n", pint, *pint); printf("%p:%c\n", pch, *pch); pch++; printf("%p:%c\n", pch, *pch); printf("%p:%.2f\n", pd, *pd); pd++; printf("%p:%.2f\n", pd, *pd); }
輸出:
0xbf944c54:1
0xbf944c58:2
0xbf944c5c:3
0xbf944c6e:a
0xbf944c6f:b
0xbf944c40:1.10
0xbf944c48:2.20
**這個結論只是對於我自己的編譯器的結果,具體可能對於另外一個編譯器的輸出有有可能不一樣,而且,如果把有變量沒有使用過的話,編譯器有可能丟棄它(自己的猜想而已,等過陣子研究《深入理解計算機系統》的時候在研究這個問題)。
3、C語言給我們的可變形參va_list
頭文件stdarg.h
下面定義了四個宏:
1. va_list
在stdarg.h中定義:typedef char * va_list;
2. void va_start(va_list ap,last);
這是第一個調用的宏,last是可變參數的前一個確定的參數。因此只有可變參數的函數是不允許的,如fun(...)是不合法的。
#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) ) //第一個可選參數地址
3. void va_arg(va_list ap, type);
返回當前參數並且使ap指向下一個參數,type是明確的類型名,就是獲取的類型,不是。
#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) ) //下一個參數地址
4. void va_end(va_list ap);
有va_start就必須有va_end,作用是使釋放ap
#define va_end(ap) ( ap = (va_list)0 ) // 將指針置為無效
4. void va_copy(va_list dest, va_list src);
每次調用va_copy時也必須要有va_end調用。
例子:
#include <stdio.h> #include <stdarg.h>
void fun(int a,...){ va_list ap; va_start(ap, a); int i; for(i=0; i<a; i++){ printf("%d\t",va_arg(ap,int)); } putchar('\n'); va_end(ap); } int main(){ fun(4,1,2,3,4); printf("--------------------------------\n"); fun(4,1,2,"ab","cd"); return 0; }
輸出:
1 2 3 4
--------------------------------
1 2 134514184 134514181