2

所以我试图熟悉c++。这是应该练习使用指针的任务。这是怎么回事:

编写一个函数,提示用户输入他或她的名字和姓氏,作为两个单独的值。此函数应通过附加指针将这两个值返回给调用者。仅当调用者为姓氏传入 NULL 指针时,它才应提示输入姓氏。

我试过几个版本。我现在坚持的是:

#include <iostream>
#include <string>

using namespace std;


void getFullName(string *p_first, string *p_last) {
    cout << "First name:";
    getline(cin, *p_first);
    if (!p_last) {
        cout << "Last name:";
        getline(cin, *p_last);
    }
}


int main() {

    string first;
    string *p_first = &first;
    string *p_last = NULL;

    getFullName(p_first, p_last);

    cout << *p_first << endl << *p_last << endl;
    return 0;
}

嗯,它崩溃了。我试图传递对“最后一个”的引用,然后指向它。但退出函数后,指针再次为 NULL。

4

5 回答 5

7

我认为练习的文本有错误,应该是:

编写一个函数,提示用户输入他或她的名字和姓氏,作为两个单独的值。此函数应通过附加指针将这两个值返回给调用者。仅当调用者为姓氏传入一个非 NULL指针时,它才应提示输入姓氏。

就目前而言,您的代码通过取消引用空指针导致未定义的行为

void getFullName(string *p_first, string *p_last) {
    cout << "First name:";
    getline(cin, *p_first);
    if (!p_last) {    /* <-- This test should be inverted */
        cout << "Last name:";
        /* Now, you get here only when p_last == NULL. On the next line, 
         * you dereference that null-pointer and try to read a string into 
         * non-existing memory: recipe for disaster.
         * With the condition inverted, you would only get here if you have 
         * a string to store the text in. */ 
        getline(cin, *p_last);
    }
}
于 2013-01-20T15:25:16.270 回答
0

不要使用指针,你不需要指针。只需通过引用传递参数:

void getFullName(string& p_first, string& p_last) 

但是,问题是您要取消引用p_last- NULL> 未定义的行为:

if (!p_last) {  //this evaluates to true, because p_last==NULL
    cout << "Last name:";
    getline(cin, *p_last);
}
于 2013-01-20T14:43:09.367 回答
0

首先,分配是错误的(如果这是完整的分配),或者您对分配的解释是错误的。这是一个读取姓氏的版本,如果 p_last 指向应该存储它的字符串:

void getFullName(string *p_first, string *p_last) {
    cout << "First name:";
    getline(cin, *p_first);
    if (p_last) {
        cout << "Last name:";
        getline(cin, *p_last);
    }
}

这是一个版本,p_last如果它不为 NULL,则用作姓氏,否则从用户读取姓氏,并且在这两种情况下都返回全名p_first

void getFullName(string *p_first, string *p_last) {
    cout << "First name:";
    getline(cin, *p_first);
    string lastname;
    if (!p_last) {
        cout << "Last name:";
        getline(cin, lastname);
    } else {
        lastname = *p_last;
    }
    *p_first += lastname;
}

这是一个版本,它使用对指针的引用来改变p_last它是否为 NULL

void getFullName(string *p_first, string *&p_last) {
    cout << "First name:";
    getline(cin, *p_first);
    if (!p_last) {
        p_last = new string;
        cout << "Last name:";
        getline(cin, *p_last);
    }
}

但是,这些都不符合您的任务。

于 2013-01-20T16:21:41.807 回答
0

它不起作用的原因是因为调用getline将字符串引用 ( basic_string<>&) 作为第二个参数,您正在取消引用空指针并将其传递。这几乎总是会出错。你需要new一个新的字符串来传递给它,但这是一个坏主意,因为它几乎肯定会导致内存泄漏,因为你已经给自己没有办法将它传递回来。

如果您传递一个指针,期望它指向的值被更改,因此充当返回值,您需要提供一个有效的指针。

于 2013-01-20T14:55:45.547 回答
0

鉴于您的问题表明您使用了额外的,我将其写为:

string getFullName()
{
    string first, last;
    cout << "First name:";
    getline(cin, first);
    cout << "Last name:";
    getline(cin, last);
    return first + last;  // note use of additional
}
于 2013-01-20T14:50:47.400 回答