【问题标题】:Why can I call a String Literal by reference but not an array?为什么我可以通过引用调用字符串文字而不是数组?
【发布时间】:2014-05-04 01:20:54
【问题描述】:

如果我的问题不清楚,请查看下面的代码。为什么字符测试有效,而整数测试无效?我很难理解的字符串文字和数组之间的根本区别是什么?

using namespace std;

void fun(int &x)
{
    cout << x << " okk" << endl;
}

void test (int* &a, int* &b) {
    int* temp = a;
    a = b;
    b = temp;
    //cout << *a << " " << &a << endl;
}

void test (char* &a, char* &b) {

    cout << &a << " " << &b << endl;
    char * temp = a;
    a = b;
    b = temp;
    //cout << *a << " " << &a << endl;
}

int main()
{
    char *s = "help";
    char *t = "me";

    char *u = "help";

    cout << s << " " << t << " " << u << endl;

    /*char *temp = s;
    s = t;
    t = temp;
    */

    test (s,t);

    cout << s << " " << t << endl;

    int a[10] = {1,2,3,4,5,6,7,8,9,10};
    int b[10] = {11,12,13,14,15,16,17,18,19,20};

    cout << *a << " " << *b << endl;

    test (a,b);

    cout << *a << " " << *b;

}

【问题讨论】:

  • 为什么要打印 char* 的地址?

标签: c++ pass-by-reference pass-by-pointer


【解决方案1】:

在第一种情况下,您使用的是指针

char *s = "help";
char *t = "me";

因此您可能会更改它们的值,因为它们不是恒定的。

考虑到字符串文字具有常量数组的类型。例如,如果您尝试拨打电话

test ("help", "me" );

你会得到一个编译错误,如下面的第二种情况。

在第二种情况下,您试图将对数组的引用转换为对指针的引用。没有这样的隐式和/或显式转换。所以编译器会报错。

如果你写的话,你可以达到与第一种情况相同的效果

int *p = a;
int *q = b;

swap( p, q );

【讨论】:

    【解决方案2】:

    在第一个字符的情况下,你是

    1. 在只读内存上实例化字符串文字
    2. 创建一个指向那里的指针(不是数组)
    3. 请求两个参数的指针引用

    所以没有问题。

    如果你是 int 的话

    1. 创建整数数组
    2. 将数组传递给一个函数,该函数需要一个指向 int 的指针的引用。

    直接使用显式指针传递时,通常说数组名称具有衰减功能。您的函数期望数组在传递给函数之前已经衰减为指针。

    在综合中,您需要在请求参考时预先匹配签名的类型。

    【讨论】:

    • 非常感谢您的回答。我在你回答后查找了数组衰减,它清除了我拥有的很多东西。
    【解决方案3】:

    我假设您的意思是:“为什么我可以通过引用传递字符串文字,而不是数组”。

    嗯,这个问题是有缺陷的,因为事实上你可以通过引用传递一个数组。您也可以通过引用传递字符串文字,但您的代码没有这样做。您的代码通过引用传递指针。

    void test (char* &a, char* &b)
    

    此函数通过引用获取两个指向 char (char*) 的指针。

    test (s,t);
    

    st 都是 char* (不是字符串文字),所以这是一个正确的调用。其他测试功能:

    void test (int* &a, int* &b)
    

    这也是通过引用获取指针(指向 int)。但是您正在尝试传递不是指针的数组。作为参考,将字符串文字(即 const 字符数组)传递给函数看起来像这样:

    test("help","me")
    

    这不会与您当前的重载一起编译。

    【讨论】:

    • 好的。我明白了。但是,这如何有效? void foo (int* a) { } int main () { int a[10];富(一); }
    • @user2910606:因为foo按值取指针,所以它可以接受右值指针。并且数组衰减为一个右值指针。但是test 函数通过非常量引用获取其参数,这需要一个左值。
    • 非常感谢。我现在明白了。
    【解决方案4】:

    int[] 不是int*,因此您不能在需要int*&amp; 引用 的地方传递int[]。但是,int[] 确实会降级为int* 指针,因此您可以将int[] 传递给预期的int*&amp; 参考有很大的不同。当您通过引用传递某些内容时,该内容必须与引用所引用的数据类型相匹配。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-25
      • 2013-09-27
      • 1970-01-01
      相关资源
      最近更新 更多