我一直试图理解将指针作为参数传递的方式。我在课程书中看到,默认情况下将指针和数组作为引用传递,但是以下程序给了我意外的结果。
我期望:
Second&First
Second*First
但是输出是:
Second&First
First*Second
我的概念是错误的还是该程序中有任何特殊技巧?请清除指针的概念。
void Alter(char* X, char* Y){
char* T;
cout<<"&S1="<<&X<<"&S2="<<&Y<<endl;
T=X;
X=Y;
Y=T;
cout<<X<<"&"<<Y<<endl;}
void main(){
char X[]="First", Y[]="Second";
cout<<"&x="<<&X<<"&y="<<&Y<<endl;
Alter(X,Y);
cout<<"&x="<<&X<<"&y="<<&Y<<endl;
cout<<X<<"*"<<Y;getch();}
答案 0 :(得分:2)
输出正确。您的期望与实际行为有所不同。
每当涉及到指针时,始终将它们视为包含某些内存地址的变量。
逐步查看正在发生的事情。
1)char X[]="First", Y[]="Second";
----------------
| F | <--- X
----------------
...
----------------
| S | <--- Y
----------------
2)cout<<"&x="<<&X<<"&y="<<&Y<<endl;
指针X
和Y
的地址输出到屏幕上。
3)Alter(X,Y);
执行此函数时,将指针X和Y复制到Alter
函数的参数,例如X'和Y'
----------------
| F | <--- X, X'
----------------
...
----------------
| S | <--- Y, Y'
----------------
4)T=X; X=Y; Y=T;
在执行此代码时,X'和Y'指针被交换。
----------------
| F | <--- X, Y'
----------------
...
----------------
| S | <--- Y, X'
----------------
5)cout<<X<<"&"<<Y<<endl;
在步骤4中可以看到,由于X指向包含'S'的存储位置,因此'Second'首先打印,而'First'随后打印。
6)cout<<"&x="<<&X<<"&y="<<&Y<<endl;
在执行该指令之前,Alter
函数的参数已超出范围。
所以,现在的场景是这样的:
----------------
| F | <--- X
----------------
...
----------------
| S | <--- Y
----------------
7)cout<<X<<"*"<<Y;
在步骤6中可以看到,因为X指向包含'F'的内存位置,所以先打印'First',然后再打印'Second'。
答案 1 :(得分:2)
是的,您的概念是完全错误的。
在您的Alter()
函数中,我在这里对其进行了简化(以删除与您的问题无关的无关输出)
void Alter(char* X, char* Y)
{
char* T;
T = X;
X = Y;
Y = T;
cout<<X<<"&"<<Y<<endl;
}
X
和Y
都是指针,它们按值传递。因此,X = Y
和Y = T
的分配对呼叫者(即main()
)不可见。具体来说,函数(X = Y
和Y = T
)中的分配对main()
无效。
但是,X
和Y
都指向(或可以用来指代)某物-在您的代码中,main()
中数组的第一个字符。函数中的那些是*X
和*Y
。一种过时的描述-似乎就是您的课程书所使用的-是它们是“通过引用传递”的东西。
如果我们要更改Alter()
以分配给*X
和*Y
,即
void Alter(char* X, char* Y)
{
char T; // note the missing * here relative to your code
T = *X; // note the added * in this line
*X = *Y; // note the added *s in this line and the next
*Y = *T;
cout<<X<<"&"<<Y<<endl; // this statement is unchanged
}
在这种情况下,输出为
Sirst&Fecond
Sirst&Fecond
(即,交换了数组的第一个字符,该效果对main()
可见)。
我们也可以将Alter()
更改为
void Alter(char*& X, char*& Y) // note the ampersands here
{
char* T;
T = X;
X = Y;
Y = T;
cout<<X<<"&"<<Y<<endl;
}
在C ++中,此处的&符号表示X
和Y
是对指针的引用。因此,此函数中的分配将对调用者可见。
但是,您的示例main()
(我再次只是为了删除无关的输出)将无法使用此功能进行编译
int main() // main() returns int in standard C++, not void
{
char X[]="First", Y[]="Second";
Alter(X,Y);
cout<<X<<"*"<<Y;
}
这将不会编译,因为X
中的Y
和main()
是数组,并且数组不是指针-因此无法将它们传递给期望传递给指针的引用的函数。这意味着您的函数Alter()
无法用于交换main()
中的数组。
答案 2 :(得分:1)
指针与传递给函数的任何其他整数一样,除了该整数对于编译器具有含义-它是内存中已定义的位置。
因此指针本身按值传递。内容他们指向的据说是通过引用传递的。
修改传递给函数的指针变量时,调用函数中指针的实际值保持不变。但是,当您修改指针所指向的值时,该值会随处更改。
在您的示例中,X和Y是指针;它们包含“第一”和“第二”的起始地址。 “第一”和“第二”分别是X和Y指向的数据。
仅使用printf
而不是cout
来考虑从程序派生的语句:
char X[] = "First";
// Prints "First"
printf("%s", X);
// Prints address of 'F' in memory
printf("%x", X);
// Prints address of X - the location where the value printed above is stored
printf("%x", &X);