在c ++

时间:2019-05-16 05:09:10

标签: c++ pointers

我一直试图理解将指针作为参数传递的方式。我在课程书中看到,默认情况下将指针和数组作为引用传递,但是以下程序给了我意外的结果。

我期望:

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();}

3 个答案:

答案 0 :(得分:2)

输出正确。您的期望与实际行为有所不同。

每当涉及到指针时,始终将它们视为包含某些内存地址的变量。

逐步查看正在发生的事情。

1)char X[]="First", Y[]="Second";

----------------
|      F       | <--- X
----------------

...

----------------
|      S       | <--- Y
----------------

2)cout<<"&x="<<&X<<"&y="<<&Y<<endl;

指针XY的地址输出到屏幕上。

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;
}

XY都是指针,它们按值传递。因此,X = YY = T的分配对呼叫者(即main())不可见。具体来说,函数(X = YY = T)中的分配对main()无效。

但是,XY都指向(或可以用来指代)某物-在您的代码中,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 ++中,此处的&符号表示XY是对指针的引用。因此,此函数中的分配将对调用者可见。

但是,您的示例main()(我再次只是为了删除无关的输出)将无法使用此功能进行编译

int main()         //  main() returns int in standard C++, not void
{
    char X[]="First", Y[]="Second";

    Alter(X,Y);
    cout<<X<<"*"<<Y;
}

这将不会编译,因为X中的Ymain()是数组,并且数组不是指针-因此无法将它们传递给期望传递给指针的引用的函数。这意味着您的函数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);