2010-01-23 115 views
2

這是一個非常簡單的問題,但下面的函數原型是什麼意思?瞭解C中的函數和指針

INT方(INT Y,爲size_t * X)

什麼劑量爲size_t *是什麼意思?我知道size_t是一個數據類型(int> = 0)。但是,我如何閱讀附加的*?它是一個指向x的內存位置的指針嗎?一般來說,我遇到了這個問題,如果有人可以提供一個方便的參考,我會很感激。


謝謝大家。我明白指針是什麼,但我想我很難理解指針和函數之間的關係。當我看到定義爲int sq(int x, int y)的函數原型時,那麼我很清楚發生了什麼事情。但是,當我看到類似int sq(int x, int* y)的東西時,我無法理解第二個參數的真正含義。在某種程度上,我明白它的意思是「傳遞一個指針」,但我不明白事情足以讓我自己操縱它。

回答

2

* x表示x是指向size_t類型的內存位置的指針。

您可以使用x =&y設置位置; 或設置值爲x指向:* x = 0;

如果您需要更多信息來看看:Pointers

10

如何在understanding pointers的教程?

但是,在這種情況下,指針可能用於修改/返回值。在C語言中,有其中一個函數可以返回一個值的兩個基本機制(請原諒啞爲例):

它可以直接返回值:

float square_root(float x) 
{ 
    if (x >= 0) 
     return sqrt(x); 
    return 0; 
} 

或者也可以通過返回一個指針:

int square_root(float x, float* result) 
{ 
    if (x >= 0) 
    { 
     *result = sqrt(result); 
     return 1; 
    } 
    return 0; 
} 

第一個被稱爲:

float a = square_root(12.0); 

...而後者:

float b; 
square_root(12.00, &b); 

注意,後者的例子還可以讓你檢查值是否恢復是真實的 - 這種機制被廣泛應用於C庫,其中一個函數的返回值通常表示成功(或缺乏它),而值本身通過參數返回。

因此與後者你可以寫:

float sqresult; 
if (!square_root(myvar, &sqresult)) 
{ 
    // signal error 
} 
else 
{ 
    // value is good, continue using sqresult! 
} 
2

原型意味着該函數採用一個整數Arg和一個ARG這是一個指向爲size_t類型。 size_t是一個在頭文件中定義的類型,通常是一個無符號整數,但不僅僅使用「unsigned int * x」的原因是爲編譯器編寫者提供了靈活性來使用別的東西。

指針是一個保存內存地址的值。如果我寫

int x = 42;

然後編譯器會在內存中分配4個字節,並在任何時候使用x來記住位置。如果我想明確地傳遞該位置,我可以創建一個指針併爲其指定x的地址:

int * ptr =&x;

現在我可以通過周圍的ptr到期望INT *爲參數的函數,我可以通過取消引用使用PTR:

COUT < < *的ptr + 1;

將打印出來43. 有很多原因可能需要使用指針而不是值。 1)當你傳遞給一個函數時,你避免了複製構造的結構和類2)你可以有一個以上的變量句柄3)它是操縱堆上變量的唯一方法4)你可以使用它們來傳遞結果通過寫入一個參數指向的位置而退出函數

+1

在附註上,我總是發現原因(4)是基於C語言的指針不幸(但有時不可避免)的用法。 – Kai 2010-01-24 00:38:25

+0

cout << * ptr + 1;是一個C++習慣用法,試試printf(「%d \ n」,* ptr + 1); – 2010-01-24 00:39:28

1

size_t *x表示您正在將指針傳遞給size_t「實例」。

有幾個原因希望傳遞一個指針。

  1. 這樣函數可以修改調用者的變量。 C使用按值傳遞,以便修改函數內的參數不會修改原始變量。
  2. 由於性能原因。如果一個參數是一個結構體,那麼按值傳遞意味着你必須複製這個結構體。如果結構足夠大,可能會導致性能下降。
0

鑑於這是一個函數的參數,還有一種解釋。

當你在一個函數的參數中使用指針(something *),並且你傳遞一個變量的時候你沒有傳遞一個值,你傳遞一個引用(一個「指針」)到一個值。對函數內部的變量所做的任何更改都會對其引用的變量(即函數外的變量)執行。

您仍然必須通過正確的類型 - 有兩種方法可以做到這一點;在調用例程中使用指針或使用&(addressof)運算符。

我剛剛寫了這個快速演示:

#include <stdio.h> 

void add(int one, int* two) 
{ 
    *two += one; 
} 

int main() 
{ 
    int x = 5; 
    int y = 7; 
    add(x,&y); 

    printf("%d %d\n", x, y); 

    return 0; 
} 

這是怎麼會事就像scanf的工作。

+1

這仍然是傳值,因爲你傳遞了一個指向函數的副本,而不是引用。 – helpermethod 2010-01-24 00:35:40

+0

謝謝大家。我明白指針是什麼,但我想我很難理解指針和函數之間的關係。當我看到一個定義爲int sq(int x,int y)的函數原型時,我很清楚發生了什麼事情。然而,當我看到類似int sq(int x,int * y)的東西時,我無法理解第二個參數的真正意義。在某種程度上,我明白它的意思是「傳遞一個指針」,但我不明白事情足以讓我自己操縱它。 – Josh 2010-01-24 01:15:51

0
int square(int y, size_t* x);

聲明一個功能有兩個參數 - 一個整數,一個指向unsigned(可能大)整數,回報一個整數。

size_t是無符號整數類型(通常是typedefreturned by sizeof() operator

*(星形)信號指針類型(例如int* ptr;使得ptr是指向整數)在使用時,在聲明所用(以及投射)時,或指針的取消引用lvalue or rvalue*ptr = 10;分配10到存儲器指向通過ptr)。這只是我們的運氣,相同的符號用於乘法(Pascal,例如,指針使用^)。

在函數聲明的位置,參數的名稱(這裏的xy)並不重要。您可以在.c文件中用不同的參數名稱定義您的功能。函數的調用者只關心函數參數的類型和數量以及返回類型。

當您定義函數時,參數現在名爲本地變量,其值由調用者分配。傳遞對象by reference時或

指針功能參數被用作輸出參數,你在一個指針傳遞給位置其中函數存儲輸出值。

C是美麗而簡單的語言:)

2

在回答你的最後的評論,我會盡力解釋。

你知道變量的值爲,值爲,變量的類型告訴你它可以容納什麼樣的值。所以一個int類型的變量可以保存一個整數,它落在一定範圍內。如果我宣佈類似功能:

int sq(int x); 

...那麼這意味着,sq功能需要你提供一個值,它是一個整數,它會返回一個值,也是一個整數。

如果一個變量是用指針類型聲明的,這意味着該變量本身的值是「另一個變量的位置」。因此,一個int *類型變量可以保存爲其值「另一個變量的位置,並且該變量具有int類型」。然後,我們可以擴展到功能:

int sqp(int * x); 

這意味着sqp函數需要你提供的值本身是一個int類型變量的位置。這意味着我可以把它像這樣:

int p; 
int q; 

p = sqp(&q); 

&q只是意味着「給我位置q,而不是它的價值」)。在sqp,我可以用這個指針這樣的:

int sqp(int * x) 
{ 
    *x = 10; 
    return 20; 
} 

*x意思是「在該位置的變量通過X特定行爲,而不是X本身」)。

+0

有人正在解決你回答他的[問題](http://stackoverflow.com/q/24449072/2455888)有關這個答案:)。 – haccks 2014-06-27 10:10:51

0

ü說,你知道什麼int sq(int x, int y) is.It意味着我們傳遞了兩個變量x,y爲aguements的功能sq.Say平方功能從main()功能稱爲在

main() 
{ 
    /*some code*/ 
    x=sr(a,b); 
    /*some other code*/ 
} 
int sq(int x,int y) 
{ 
    /*code*/ 
} 

任何操作完成在X,Y在平方功能不會影響值A,b 而在

main() 
{ 
    /*some code*/ 
    x=sq(a,&b); 
    /*some other code*/ 
} 
int sq(int x,int* y) 
{ 
    /*code*/ 
} 

Y上做將修改b的值,因爲我們指到b

操作

所以,如果你想修改原始值,使用指針。 如果你想使用這些值,那麼不需要使用指針。

0

上面的大部分解釋都很好地解釋了。我想添加這種參數傳遞的應用觀點。當一個函數必須返回多個值時,它不能通過使用多個返回類型來完成(平凡,而且我們都知道)。爲了實現將函數的傳遞指針作爲參數來實現,提供一種方式來反映所做的內部被調用的函數的變化(如:開方)中調用函數(如:主)

如:愚蠢,但給你一個場景

//a function is used to get two random numbers into x,y in the main function 
int main() 
{  
int x,y;  
generate_rand(&x,&y);  
//now x,y contain random values generated by the function 
} 

void generate_rand(int *x,int *y) 
{ 
*x=rand()%100; 
*y=rand()%100; 
} 

2)經過時一個對象(一個類的對象或一個結構等)是一個代價高昂的過程(即如果這個尺寸太大,那麼內存和其他約束等)

例如:不是將一個結構作爲參數傳遞給一個函數,這個指針可能很方便,因爲指針可以用於訪問結構,但是也可以節省內存,因爲您不會將結構存儲在臨時位置(或堆棧)

只是一對夫婦的例子..希望它有助於..

0

2年,仍然沒有答案接受?好吧,我會盡量解釋它...

讓我們帶你已經在你的問題中提到的兩個功能:

int sq_A(int x, int y)

你知道這一點 - 這是一個叫sq_A函數,它接受兩個int參數。簡單。

int sq_B(int x, int* y)

這是一種稱爲sq_B函數,它接受兩個參數:

  • 參數1是一個int

  • 參數2是一個指針。這是一個指向int

所以,當我們調用sq_B(),我們需要傳遞一個指針作爲第二個參數 的指針。我們不能只傳遞任何指針 - 它必須是指向int類型的指針。

例如:

int sq_B(int x, int* y) { 
    /* do something with x and y and return a value */ 
} 

int main() { 
    int t = 6; 
    int u = 24; 
    int result; 

    result = sq_B(t, &u); 

    return 0; 
} 

main(),可變uint。要獲得指向u的指針,我們 使用&運算符 - &u。這意味着「地址u」,並且是一個 指針。

因爲uint&u是一個指向一個int(或int *),這是通過sq_B()參數2指定的類型。

有任何問題嗎?