1. 程式人生 > >C語言引數傳遞----值傳遞與地址傳遞

C語言引數傳遞----值傳遞與地址傳遞

最近開始復(yu)習(xi)C語言,看到引數傳遞這裡,又遇到了以前一直沒有搞清楚的一個問題,我相信這個問題大家許多初學者也會遇到過,就是C語言函式的引數傳遞方式。
C語言中引數的傳遞有兩種方式:
1)值傳遞
2)地址傳遞
3)陣列作為函式引數
這裡用兩個例子來說明這兩種方式的區別。

  • 值傳遞

int main(){
    int a=3;
    int b=4;
    printf("初始值a=%d,b=%d\n",a,b);
    exchange(a,b);
    printf("執行後a=%d,b=%d",a,b);
    return 0;
}
void exchange(int
a ,int b){ int temp; temp=a; a=b; b=temp; }

執行結果:這裡寫圖片描述

  • 地址傳遞
int main()
{
    int i,j,k;
    int data[100];
    int length=3;
   int a=3;
    int b=4;
    printf("初始值a=%d,b=%d\n",a,b);
    exchange(&a,&b);
    printf("執行後a=%d,b=%d",a,b);
}

void exchange(int  *a ,int *b){
    int
temp; temp =*a; *a=*b; *b=temp; }

執行結果:這裡寫圖片描述

why?
老生常談的問題了,我們預期的是ab的值會交換,但是並沒有達到預期的效果,因為這個函式使用的是值傳遞。
我個人是這樣的理解的,main函式中宣告的ab兩個變數,看作是計算機中的兩個盤子A,B。A盤子中放的是“3”,B盤子中放的是“4”。
值傳遞的方式,只是把兩個盤子中的東西作為引數傳入,起到的是一種模板作用,函式收到這兩個引數之後,會找到另外兩個跟“3”“4”一樣的東西,對這兩個東西進行操作。而並不會改變main中原來兩個盤子的值。而地址傳遞,就是把A,B這個兩個盤子作為引數傳過去了,進行的操作會影響到這個盤子裡的東西。
換言之,我們去飯店點菜,有時大廳中能看到保鮮膜裹著的樣品菜,我們指著桌上盛放“魚香肉絲”的盤子告訴服務員我們要這個菜,廚師會另取相同的食材

做出我們點的“魚香肉絲”,而原本放在大廳裡的樣菜並沒有動。—-這是值傳遞。
相反,我們跟服務員說,我們就要這個盤子裡的菜,這樣廚師就直接烹飪了我們指定的盤子裡的菜。—-這是地址傳遞。

另外還看到一種引用傳遞,是c++語言中引數的傳遞方式,宣告格式如下

void exchange(int &a,int &b){
/*操作*/
}

另外需要注意的是,C語言中使用地址傳參,宣告的格式是void function(int *a)
而呼叫的格式是:function(&a)
因為傳遞的引數是地址,所以在呼叫時候要有“&”取地址符號!

  • 陣列作為函式引數
    1)陣列元素作為函式引數,函式的宣告沒有什麼差別,還是分為上述的兩種方式:void function(int a);//值傳遞或者是void function(int *a);//地址傳遞,呼叫函式時分別採用function(a[2]);或者function(&a[2]);這種情況下,存在值傳遞與地址傳遞的不同,參考上述。
    2)陣列名作為引數傳遞:
    例如function(int a[])
    呼叫函式:function(a);//這裡a是一個數組名字
    用陣列名做函式實參時,不是把陣列元素的值傳給形參,而是把實引數組的首元素的地址傳遞給形式引數,也就是說形引數組發生改變,會使實引數組發生同樣的變化。換言之,函式進行的操作就是直接發生在傳遞進來的陣列上的。
    下面舉一個例子,對陣列a中的數字進行排序
#include stdio.h
int main()
{
    int i;
    int n=6;
    int a[6]={7,5,3,4,12,54};
    for(i=0;i<n;i++) printf("%d ",a[i]);
    printf("\n排序之後\n");
    Sort(a,n);
     for(i=0;i<n;i++) printf("%d ",a[i]);
    return 0;
}

void Sort(int a[],int n){
    int i,j;
    int tmp=0;
    for(i=0;i<n;i++){
        for(j=0;j<n-1-i;j++){
            if(a[j]>a[j+1]){
                tmp=a[j];
                a[j]=a[j+1];
                a[j+1]=tmp;
                }
        }
    }
}

執行結果:這裡寫圖片描述

可以看出,函式名作為引數時,所做的操作會直接影響原來的陣列。

相關推薦

C語言引數傳遞----傳遞地址傳遞

最近開始復(yu)習(xi)C語言,看到引數傳遞這裡,又遇到了以前一直沒有搞清楚的一個問題,我相信這個問題大家許多初學者也會遇到過,就是C語言函式的引數傳遞方式。 C語言中引數的傳遞有兩種方式: 1)值傳遞 2)地址傳遞 3)陣列作為函式引數 這裡用兩

誤人子弟篇之C語言函式返回引數傳遞

寫在開頭以免看到結尾你,此篇部落格純屬瞎扯,看看就可以了,不要當真哦! 如果搞過彙編,寫過子程式,那麼你就不用看了,因為看到最後你會發現,在彙編中你有很多方法去返回值,傳遞引數,而在高階語言中,編譯器只是選擇了其中的一種而已,而這篇部落格也寫的毫無邏輯,簡直喪盡天良,草菅人

物件作為引數傳遞地址傳遞

1.沒有明確宣告為指標或者引用,都是值傳遞,會呼叫物件過載的=,建立新的物件。2.當指定為指標型別的時候為傳遞的是指標(地址),指定引數型別為引用的時候,傳遞的也是地址。#include<stdi

C/C++語言引數傳遞----傳遞、引用傳遞、指標傳遞、指標引用傳遞

1.值傳遞 void f( int p){ printf("\n%x",&p); printf("\n%x",p); p=0xff; } void main() { int a=0

## 標題:指標的傳遞地址傳遞,全域性變數傳遞形參傳遞的區別結果

標題:指標的值傳遞與地址傳遞,全域性變數傳遞,與形參傳遞的區別與結果 1.值傳遞與地址傳遞 下面看著段程式碼:void swap(int a, int b){ int t; t=a; a=b; b=t; } void swap1(int *p1,int *p2){ int t; t=*p

傳遞地址傳遞

作為開發人員,入門級的理解,就是值傳遞和地址傳遞的區別,這是C語言中的基礎。今天通過一個oc的demo理解一下面向物件中的值傳遞和地址傳遞,首先定義一個自定義類MyFunction,定義值傳遞和地址傳遞的方法 -(int)byValue:(int)x { x++; return x

徹底高清傳遞地址傳遞的區別

1. 考題一:程式程式碼如下:void Exchg1(int x, int y)  {  int tmp;  tmp=x;  x=y;  y=tmp;  printf(“x=%d,y=%d/n”,x,y)}void main(){  int a=4,b=6;  Exchg1

java 傳遞地址傳遞(引用)的區別

JAVA傳遞引數有兩種方式:值傳遞和引用傳遞 值傳遞是傳遞資料:如基本資料型別都是值傳遞 引用傳遞是把形參和實參的指標指向了堆中的同一物件,物件的引用和陣列的引用。 注意: 實參,J

函式的傳遞地址傳遞--以輸入三個數並從小到大排列為例

一、值傳遞 #include <stdio.h> //自定義函式實現三個數從小到大排列 //值傳遞 //編者:wsg void sort(int a, int b, int c) { int t; if(a>b) { t = a;

C語言精要總結-內存地址對齊struct大小判斷篇

超過 等於 合規 占用 編譯 約定 long 並發 分享 在筆試時,經常會遇到結構體大小的問題,實際就是在考內存地址對齊。在實際開發中,如果一個結構體會在內存中高頻地分配創建,那麽掌握內存地址對齊規則,通過簡單地自定義對齊方式,或者調整結構體成員的順序,可以有效地減少內存使

C語言之struct大小、首地址記憶體對齊—由結構體成員地址得到結構體首地址

被問到如下問題:給定一個結構體中某個變數地址,可否得到結構體變數的地址? 答案是可以,但是對不同的場合有不同的結果;這與微處理器平臺、編譯器的處理不可分割。 首先,對於處理器,大尾端、小尾端的因素必須考慮; 其次: 一、 ANSIC標準中並沒有規定,相鄰宣告的變數在記憶體中一定要相鄰。 為了程式的高效性,

【疑問解答】地址的位數不是和作業系統有關嗎?為什麼我的是64位的作業系統,寫的C語言程式,裡面的變數地址是32位的?

問:地址的位數不是和作業系統有關嗎?為什麼我的是64位的作業系統,寫的C語言程式,裡面的變數地址是32位的? 答:你說你的系統是64位,但是,不知您的C編譯程式採用了什麼模式。 具體的C編譯程式有不同的模式,如“微模式”、“小模式”、“中模式”、“大模式”、“巨模式”等等。

C語言程式設計基礎-09函式返回及形參

函式 返回值 形參實參 函式 在大規模的程式中需要對語句進行分組管理,把相互之間聯絡比較緊密的語句合併成一組; 分組可以在多個不同層次上進行,最低一級分組的結果叫程式碼塊,程式碼塊由{}大括號包括; 在大括號前面新增     型別名 函式名()的就是函式; 函式的形式如 v

c語言字符數組字符串的使用詳解

變量名 () 有效 檢測 指針變量 增加 ram 字符串 系統 轉自http://www.jb51.net/article/37456.htm 1、字符數組的定義與初始化字符數組的初始化,最容易理解的方式就是逐個字符賦給數組中各元素。char str[10]={ ‘I‘,‘

C語言復雜表達式指針應用

平臺無關 變量類型 pin 同時 oid 復雜 數組 多個 定義 基礎知識 (1)指針數組:int *a[10]     理解:a和[]先結合,構成數組a[10](同時說明這變量的本質是數組,所以最終應該叫做**數組),緊接著與*號結合說明這個數組中10個元素都是指針,且指

c語言cJson數組生成解析

scu 長度 c語言 數組 != res bject urn dds 1.生成 json char* CreatJsCustNo( BT_BNF_CUST *p, char *strPaperNO) { cJSON *pJsonArry,*pJsonsub;

C語言----結構體---結構體函數

urn 全局變量 月的天數 [] strong ret 例子 c語言 += 結構作為參數的函數 整個結構可以作為參數傳入函數 這時是在函數中新建了一個結構變量,並復制調用這個結構的值(重點,只是把值傳入函數,而函數外面真正的變量並沒有改變,與數組不同) 函數也可以返

C語言中的強符號弱符號

_weak 多個 obj china 很難 字節 whole sta dump 註意,強符號和弱符號都是針對定義來說的,不是針對符號的引用。 一、概述 在C語言中,函數和初始化的全局變量(包括顯示初始化為0)是強符號,未初始化的全局變量是弱符號。 對於它們,下列三條規則使用

嵌入式C語言開發---存儲器寄存器

orf inf 麻煩 gpio 區分 連續 寄存器 不足 div 概述: 講述如何使用C語言來對底層寄存器進行封裝 內容: 存儲器映射 寄存器與寄存器映射 C語言訪問寄存器 存儲器映射 程序存儲器、數據存儲器、寄存器和I/O 端口排列在同一個順序的4 GB 地址空間內

C語言 內存四區函數調用模型

eas 賦值 預算 誰的 初始 int abcdefg AI 常亮 C語言提高筆記