1、指針變量的賦值,分為定義時賦值(初始化)和單獨賦值,如:
成都創(chuàng)新互聯(lián)公司是一家集網站建設,樺甸企業(yè)網站建設,樺甸品牌網站建設,網站定制,樺甸網站建設報價,網絡營銷,網絡優(yōu)化,樺甸網站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強企業(yè)競爭力??沙浞譂M足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網需求。同時我們時刻保持專業(yè)、時尚、前沿,時刻以成就客戶成長自我,堅持不斷學習、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實用型網站。
int x ;
int * px=x ; //定義時賦值,也稱初始化,注意這里的*是跟隨int的,即變量px是int *類型變量! 實際上的賦值語句是px=x ;
int * py ;
py=x ; //單獨賦值,將py指向x
*py=10 ; //這里的*,是引用指針中的數據操作符,*跟隨的變量必須是指針類型變量,否則會出錯! *py就是x,這里相當于x=10;
2、指針變量作為函數的參數時,子函數可以通過指針引用實參地址中的數據,達到修改實參地址中的數據。如:
#include stdio.h
void func( int a, int b, int *pmax )
{
if ( ab ) *pmax=a;
else *pmax=b ;
}
void main()
{
int a=2,b=3,max=0;
func(a,b,max ); //這里將變量max的地址傳遞到子函數,子函數中通過該地址,可以修改max的值,達到子函數結束后,max能帶回運算結果的效果。
printf("max=%d\n", max );
}
#include
void
foo(int
x,
int
y,
int
z)
{
printf("x
=
%d
at
[%x]n",
x,
x);
printf("y
=
%d
at
[%x]n",
y,
y);
printf("z
=
%d
at
[%x]n",
z,
z);
}
int
main(int
argc,
char
*argv[])
{
foo(100,
200,
300);
return
0;
}
運行結果:
x
=
100
at
[bfe28760]
y
=
200
at
[bfe28764]
z
=
300
at
[bfe28768]
c程序棧底為高地址,棧頂為低地址,因此上面的實例可以說明函數參數入棧順序的確是從右至左的。可到底為什么呢?查了一直些文獻得知,參數入棧順序是和具體編譯器實現相關的。比如,pascal語言中參數就是從左到右入棧的,有些語言中還可以通過修飾符進行指定,如visual
c++.即然兩種方式都可以,為什么c語言要選擇從右至左呢?
進一步發(fā)現,pascal語言不支持可變長參數,而c語言支持這種特色,正是這個原因使得c語言函數參數入棧順序為從右至左。具體原因為:c方式參數入棧順序(從右至左)的好處就是可以動態(tài)變化參數個數。通過棧堆分析可知,自左向右的入棧方式,最前面的參數被壓在棧底。除非知道參數個數,否則是無法通過棧指針的相對位移求得最左邊的參數。這樣就變成了左邊參數的個數不確定,正好和動態(tài)參數個數的方向相反。
因此,c語言函數參數采用自右向左的入棧順序,主要原因是為了支持可變長參數形式。換句話說,如果不支持這個特色,c語言完全和pascal一樣,采用自左向右的參數入棧方式
c語言中形參與實參的關系是:形參是實參的值副本。無論參數的類型是什么,傳遞到子函數中的形參只是實參的值。所以,在改變形參變量自身的值時,是與實參無關的。換句話說,形參的改變不會影響到實參。
但,如果參數類型是指針類型,則可以通過對指針變量所指向的地址中的數據進行修改,達到改變實參地址中的數據目的。
因此,使用swap函數進行數據交換時,必須保證兩點:
1.
參數必須是指針類型,指向待交換的數據
2.
交換時,必須交換地址中的數據,而不是交換地址本身。
參考代碼:
//錯誤的交換代碼1
void swap1( int a, int b ) //參數不是待交換數據的指針
{
int t=a;
a=b;
b=t;
}
//錯誤的交換代碼2
void swap2( int *a, int *b )
{
int *t=a;//交換形參變量本身
a=b;
b=t;
}
//正確的交換代碼
void swap( int *a, int *b )
{
int t=*a;//交換形參變量地址中的數據,指針變量不變
*a=*b;
*b=t;
}
如@psxf91所答,應使用v*系列的函數來實現。對比下printf與vprintf函數原型:
void?printf(const?char?*format,?...);
void?vprintf(const?char?*format,?va_list?ap);
可以看出二者的差別。vprintf才接收va_list類型,printf接收的是不定參數。
因此,要實現你的要求代碼如下:
#include?"stdarg.h"
void?fun(const?char?*fmt,?...){
va_list?ap;
va_start(ap,?fmt);
//?...
vprintf(fmt,?ap);
//?...
va_end(ap);
}
需要借用C語言的VA_LIST?宏定義,及相關操作來實現可變參數。
VA_LIST?所在頭文件:#include stdarg.h,用法如下:
(1)首先在函數里定義一具VA_LIST型的變量,這個變量是指向參數的指針;
(2)然后用VA_START宏初始化剛定義的VA_LIST變量;
(3)然后用VA_ARG返回可變的參數,VA_ARG的第二個參數是你要返回的參數的類型(如果函數有多個可變參數的,依次調用VA_ARG獲取各個參數);
(4)最后用VA_END宏結束可變參數的獲取。
以下是一個自定義打印接口的實現:
int?my_printf(const?char?*fmt,?...)//...表示參數可變
{
va_list?args;//定義va_list
static?char?gc_PrintfOutBuff[1000];
va_start(args,?fmt);//初始化
vsnprintf((char?*)?gc_PrintfOutBuff,?1000,?(char?*)?fmt,?args);//這里沒有使用VA_ARG取回單個變量,而是借用vsnprinf一次性讀取。
va_end(args);//結束獲取
puts("%s",(const?char?*)gc_PrintfOutBuff);//使用。
return?0;
}
當前文章:c語言函數指針可變參數 c 可變參數函數
文章來源:http://jinyejixie.com/article42/dodppec.html
成都網站建設公司_創(chuàng)新互聯(lián),為您提供微信公眾號、網站維護、手機網站建設、網站收錄、網站改版、外貿建站
聲明:本網站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)