C語言小結 輸入型引數和輸出型引數

2021-08-20 21:59:39 字數 2784 閱讀 6337

(1) 函式的作用就是處理資料,傳入的引數就是被加工的資料,返回值就是輸出的結果。

(2)函式名就是這個函式的入口,在記憶體中表示就是乙個函式**段的首位址,實質是乙個指標常量,所以在程式中使用函式名都是當位址來用的,用來呼叫這個函式。再理解指標函式的實質就比較簡單了。

(3) 如果乙個函式沒有傳參和返回值,也是可以的,也可以正常執行,那麼沒有返回值和形參的函式怎麼執行呢?為什麼會有這種函式呢?其實這種型別的函式在c語言中有很多。主要有兩個作用:1) 在系統初始化的時候,我們做一些系統的配置工作,這種型別的函式都是一些配置函式,不需要形參。2)我們處理一些全域性變數的資料時,會用到這種型別的函式。

我們舉個例子來說明一下什麼是輸入型引數,什麼是輸出型引數。

int

func(int

a , int

*p)int main()

執行結果:

root@ubuntu

:/mnt/hgfs/share/code/c_advance/pointer

# ./a.out

x = 10

y = 20

結論:

(1) func函式中a是輸入型引數,p是輸出型引數。

(2) 形參的傳值呼叫是輸入型引數。傳址呼叫即有可能是輸出型引數,也有可能是輸入型引數。作為輸入型引數使用時,一般會加入const關鍵字,表明是唯讀,不能修改。

今天又發現了乙個有趣的現象。事情是這樣的:我需要申請一塊記憶體空間,然後使用strcpy來拷貝乙個字串,最後printf列印,直接上**:

#include 

#include

#include

void

getmemory(char

*p)int main(void

)

執行結果如下:

void@ubuntu

:/mnt/hgfs/vmshare/code/c

$ ./a.out

&str = 0xbfce7718

str = (nil

)getmemory

getmemory

: 0x81ab410

segmentation

fault (core dumped)

結果分析:報了段錯誤,為什麼呢?char *str;是乙個區域性變數,我們傳入區域性變數然後還想要修改該區域性變數的值,這是不科學的,也是不合理的。這種雖然也是傳址呼叫,但是本質上還是傳值呼叫。說的有點繞,需要仔細體會下。 這種傳遞和上邊的傳入變數x的效果是一樣的。

那麼怎麼改呢?

兩個思路:

1、將char *str = null;定義為全域性變數,這樣我們是把位址空間傳遞給了乙個全域性變數,這樣函式返回的時候位址空間還在。已驗證,就不貼**和執行結果了。

2、我們使用二維指標來試一下,直接上**:

#include 

#include

#include

void

getmemory2(char

**p)

int main(void

)

執行結果如下:

void@ubuntu

:/mnt/hgfs/vmshare/code/c

$ ./a.out

main:

&str = 0xbff03f88

str = (nil

)getmemory2

&p = 0xbff03f70

p = 0xbff03f88

*p = 0x8c6d410

str = 0x8c6d410

&str = 0xbff03f88

hello world

滿足了我們的要求。

函式在傳參的時候,其實在棧空間又複製了乙份,比如我們定義函式:int fun(int x),當我們在呼叫fun(10);的時候,其實編譯器內部操作可以看為兩步:int x ; x = 10;,且在呼叫完成後釋放該函式申請的變數。我們再看一下這個函式:void getmemory(char *p),在被呼叫的時候,函式內部申請了乙個char *p的變數,所以我們把這個變數的值是傳遞不到呼叫的函式內部的。

我們定義:void getmemory2(char **p),雖然它內部也定義了乙個變數char **p = &str,我們看到被分配了位址空間:0xbff03f70。但是*p指向了malloc申請出來的記憶體空間。所以我們的str也指向了malloc申請的記憶體空間。當函式呼叫結束,**p被釋放,但是str指向的記憶體空間的位址確沒有改變,所以就可以正常呼叫了。換句話說,我申請了乙個二重指標指向你,然後修改了你的指向(本來指向null,後來指向malloc申請出來的空間),然後我申請的二重指標被釋放掉,但是你的指向還在。

引申:其實傳址呼叫和c++語言的引用&很相似,但又有一點不同(傳參呼叫本身也申請了變數),但是本質都是一樣的,我用多個指標變數指向同一塊記憶體,這個指標修改完被釋放,但是還有其他指標指向該記憶體,以此來達到間接修改的目的。在python中,我們也可以使用多個變數來指向同乙個物件,當沒有變數指向這個物件的時候,物件空間就會被自動**。

最後,c語言是一門博大精深的語言,需要我們認真體會。

**:

C指標之輸入型引數與輸出型引數

其實如果沒有形參列表和返回值,函式也能對資料進行加工,用全域性變數即可。全域性變數傳參最大的好處就是省略了函式傳參的開銷,所以效率要高一些 int multip5 int a void multip5 2 void int x 被乘5的變數,也就是輸入函式的變數 int y 輸出結果的變數 int ...

回型輸入和回型輸出

輸入m,n,輸出乙個m n的回型 順時針方向 矩陣,再回型 逆時針方向 輸出 對於是順時針輸入還是逆時針輸入,只需要更改初始x,y值就行。順時針 x 0,y 1 逆時針 x 1,y 0即可。至於為什麼是 1,是因為為了程式設計的方便以及避免自加後越界導致需要減回邊界 這裡使用的是迴圈較為方便,經過分...

小結 C語言的輸入和輸出

因為一直學c 不熟悉c。通過乙個例子來學c的輸入和輸出。include include include using namespace std int main int argc,char argv 1 scanf控制輸入格式,f表示輸入浮點數,必須要有 不要寫成 lf lf n r,h 雖然不知道...