[英]What does int & mean
一個 C++ 問題,
我知道
int* foo(void)
foo 將返回一個指向 int 類型的指針
怎么樣
int &foo(void)
它返回什么?
非常感謝!
它返回對 int 的引用。 引用類似於指針,但有一些重要的區別。 我建議您閱讀指針、引用、對象和原始數據類型之間的區別。
“Effective C++”和“More Effective C++”(均由 Scott Meyers 撰寫)對差異以及何時使用指針與引用進行了很好的描述。
編輯:有很多答案說“引用只是語法糖,以便於處理指針”。 他們肯定不是。
考慮以下代碼:
int a = 3;
int b = 4;
int* pointerToA = &a;
int* pointerToB = &b;
int* p = pointerToA;
p = pointerToB;
printf("%d %d %d\n", a, b, *p); // Prints 3 4 4
int& referenceToA = a;
int& referenceToB = b;
int& r = referenceToA;
r = referenceToB;
printf("%d %d %d\n", a, b, r); // Prints 4 4 4
行p = pointerToB
改變了p
的值,即它現在指向另一塊內存。
r = referenceToB
做了一些完全不同的事情:它將b
的值分配給a
的值。 它根本不會改變r
。 r
仍然是對同一塊內存的引用。
差異是微妙的,但非常重要。
如果您仍然認為引用只是指針處理的語法糖,那么請閱讀 Scott Meyers 的書籍。 他可以比我更好地解釋差異。
在這里要小心……您正在走 C/C++ 路線。 有一個非常明顯的區別,但並不總是這樣:
C++ :這通常意味着引用。 例如,考慮:
void func(int &x)
{
x = 4;
}
void callfunc()
{
int x = 7;
func(x);
}
因此, C++可以按值傳遞或按引用傳遞。
然而, C沒有這樣的引用傳遞功能。 & 表示“addressof”,是一種從變量制定指針的方法。 但是,考慮一下:
void func(int* x)
{
*x = 4;
}
void callfunc()
{
int x = 7;
func(&x);
}
看似相似,卻有着本質的不同。 您在C中所做的是傳遞指針的副本。 現在這些東西仍然指向同一個內存區域,所以就所指向的內存而言,效果就像是通過引用傳遞,但傳入的不是引用。它是對內存中某個點的引用。
試試這個(編譯為 C):
#include <stdio.h>
void addptr(int* x)
{
printf("Add-ptr scope 1:\n");
printf("Addr: %p\n", x);
printf("Pointed-to-memory: %d\n", *x);
*x = *x + 7;
x++;
printf("Add-ptr scope 2:\n");
printf("Addr: %p\n", x);
printf("Pointed-to-memory: %d\n", *x);
}
int main(int argc, char** argv)
{
int a = 7;
int *y = &a;
printf("Main-Scope 2:\n");
printf("Addr: %p\n", y);
printf("Pointed-to-memory: %d\n", *y);
addptr(y);
printf("Main-Scope 2:\n");
printf("Addr: %p\n", y);
printf("Pointed-to-memory: %d\n", *y);
return 0;
}
如果 C 通過引用傳遞,則傳入指針地址在被addptr
更改時應該反映在main
中,但事實並非如此。 指針仍然是值。
因此, C沒有任何引用傳遞機制。 在 C++ 中,這存在,這就是 & 在函數參數等中的含義。
編輯:您可能想知道為什么我不能輕松地在 C++ 中進行此演示。 這是因為我無法更改引用的地址。 完全沒有。 從他相當好的參考指南:
如何重新設置引用以使其引用不同的對象?
沒門。
您無法將引用與所指對象分開。
與指針不同,一旦引用綁定到一個對象,它就不能“重新定位”到另一個對象。 引用本身不是一個對象(它沒有身份;獲取引用的地址可以得到引用的地址;記住:引用是它的引用)。
從這個意義上說,引用類似於 const 指針,例如 int* const p(與指向 const 的指針,例如 int const* p 不同)。 但請不要將引用與指針混淆; 從程序員的角度來看,它們非常不同。
根據要求,在返回參考資料時:
#include <iostream>
using namespace std;
int& function(int f)
{
f=f+3;
return f;
}
int main(int argc, char** argv)
{
int x = 7;
int y;
y = function(x);
cout << "Input: " << x << endl;
cout << "Output:" << y << endl;
return 0;
}
任何好的編譯器都應該以某種形式給你這個警告信息:
exp.cpp:7:11:警告:對與局部變量“f”關聯的堆棧內存的引用返回
這是什么意思? 好吧,我們知道函數參數被壓入堆棧(注意:實際上不是在 x64 上,它們進入寄存器然后進入堆棧,但它們在 x86 上實際上在堆棧上),這個警告的意思是創建對此類的引用一個對象不是一個好主意,因為它不能保證留在原地。 事實上,這只是運氣。
那么給了什么? 試試這個修改后的版本:
#include <iostream>
using namespace std;
int& function(int& f)
{
f=f+3;
return f;
}
int main(int argc, char** argv)
{
int x = 7;
int y;
y = function(x);
cout << "Input: " << x << endl;
cout << "Output:" << y << endl;
return 0;
}
運行這個,你會看到兩個值都更新了。 什么? 好吧,他們都指的是同一件事,而那件事正在被編輯。
它返回對 int 變量的引用。
這個問題根本不是 C/C++,因為 C 沒有引用,只有指針。 int& 是對 int 的引用。 此外,您不需要void
,它可以只是int& foo();
來自阿爾弗雷德的評論
文檔是這么說的,德州儀器的 TMS320C28x C/C++ 編譯器內在函數,第 122 頁,int&__byte(int, unsigned int),我猜它和 PC 不一樣 – Alfred Zhong
從手冊:
int &__byte(int *array, unsigned int byte_index);
MOVB 數組[byte_index].LSB, src
C28x 中的最低可尋址單元是 16 位。 因此,通常不能訪問 8 位 MOVB dst, array[byte_index]。 LSB 實體離開內存位置。 此內在函數有助於訪問內存位置的 8 位數量,並且可以按如下方式調用:
__byte(array,5) = 10;
b = __byte(array,20);
這只是意味着該函數返回對一個整數的引用,該整數的作用類似於 8 位量。 因為值是一個引用,修改將修改目標處的對象(就像 MOVB)指令,而分配給 b 將復制(就像 MOVB)到目標。
只是玩變量來向您展示含義
int i = 5;
int * pI = &i;
int & referenceToI = * pI;
referenceToI = 4; // now i == 4
編輯:引用只是更容易處理指針的語法糖。 在匯編級別,編譯器生成的代碼返回給你一個地址指針
https://isocpp.org/wiki/faq/references
這一頁說的很簡潔! 引用是別名。 它是對象,只是另一個名稱。 以前的名稱仍然有效。 引用不是獨立對象。 它是不同名稱的對象。 您不能對引用進行操作,因為它本身不是事物。 它只是原始對象的別名。
就是這么簡單。 現在您可以輕松地想到它,而不是上面的帖子中的一輪又一輪。
int& 是一個參考。 更准確地說,引用變量只是現有變量的替代名稱。
示例:考慮下面的代碼
main(){
int x = 4;
int& ref_of_x = x;
// Now, modifying x modifies ref_of_x too and vice-versa
x = 5;
cout<<ref_of_x; //This prints 5
ref_of_x = 15;
cout<<x; // This prints 15
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.