c++这里为什么不用指针就是错的

c++我不知道为什么这个地方用指针就是对,不用就是错
部分代码如下,其中被注释掉的就是换成指针的部分,外层函数输入(addressBook abs),里面也用abs.personArr[]就不太行,必须是addressBook*abs配abs->personArr[]

#include<iostream>
#include<string.h>
using namespace std;

struct  person
{
    string name;
    string sex;
    int age;
    string number;
    string address;
};

#define max 1000

struct addressBook
{
    int size;
    person personArr[max];
};

int detect(addressBook abs,string name)
{
    for (int i = 0; i < abs.size; i++)
    {
        if (abs.personArr[i].name==name)
        {
            return i;
        }
    }
    return -1;
}
void findPerson(addressBook abs)
{
    string name;
    cout << "请输入要查找的联系人姓名:" << endl;
    cin >> name;
    /*int ret = detect(*abs, name);
    if (ret == -1)
    {
        cout << "没有找到联系人信息,请重新输入" << endl;
    }
    else
    {
        cout << "性别:" << abs->personArr[ret].sex << "\t"
            << "年龄:" << abs->personArr[ret].age << "\t"
            << "联系电话:" << abs->personArr[ret].number << "\t"
            << "住址:" << abs->personArr[ret].address << endl;
    }    */
    int ret = detect(abs, name);
    if (ret == -1)
    {
        cout << "没有找到联系人信息,请重新输入" << endl;
    }
    else
    {
        cout << "性别:" << abs.personArr[ret].sex << "\t"
            << "年龄:" << abs.personArr[ret].age << "\t"
            << "联系电话:" << abs.personArr[ret].number << "\t"
            << "住址:" << abs.personArr[ret].address << endl;
    }
    system("pause");
    system("cls");

}

该回答引用ChatGPT-3.5,仅为您提供参考,不保证完全正确
在你的代码中,addressBook 结构体包含了一个数组 personArr,而 detect 函数和 findPerson 函数都接受一个 addressBook 结构体作为参数。在这两个函数中,你有两种不同的方式来访问 personArr 中的元素,一种是使用指针,另一种是直接使用结构体的实例。


下面我将解释为什么这两种方式不同:

  1. 使用指针:

    int ret = detect(*abs, name);
    

    在这种情况下,你传递了 abs 的指针,然后在 detect 函数内部使用 *abs 来访问结构体的实例。这实际上是在函数内部使用的是结构体的一个拷贝,而不是原始结构体,因此你需要使用 abs->personArr[ret] 来访问其中的数组元素。

  2. 直接使用结构体的实例:

    int ret = detect(abs, name);
    

    在这种情况下,你直接传递了 abs 的实例,因此在 detect 函数内部,你可以使用 abs.personArr[ret] 来访问数组元素,因为你操作的是原始结构体的实例。


总结:如果你不使用指针,而是直接传递结构体实例,那么你可以使用 abs.personArr[ret] 来访问数组元素,因为你操作的是原始结构体。如果你使用指针,那么需要使用 abs->personArr[ret] 来访问数组元素,因为你操作的是指向结构体的指针。


该回答引用NewBing,仅为您提供参考,不保证完全正确
你好,这是 Bing。我看了你的代码,我觉得你的问题可能是因为你的函数参数是按值传递的,而不是按引用或指针传递的。按值传递的话,函数内部对参数的修改不会影响到原来的对象,而按引用或指针传递的话,就可以修改原来的对象。所以,如果你想在函数内部改变 addressBook 的内容,你就需要用指针或引用作为参数,而不是直接用 addressBook 对象。


源: 与必应的对话, 2023/9/8
(1) C++笔记——参数传递中的指针传递和引用传递 - 知乎. https://zhuanlan.zhihu.com/p/130464385.
(2) C++编程:为什么要用指针,而不直接使用对象? - 知乎. https://zhuanlan.zhihu.com/p/54066512.
(3) C++指向结构体变量的指针 - 知乎 - 知乎专栏. https://zhuanlan.zhihu.com/p/340785518.
(4) c语言入门 第二十一章 结构体与指针 - 知乎 - 知乎专栏. https://zhuanlan.zhihu.com/p/148394403.


该回答引用文心一言,仅为您提供参考,不保证完全正确
你的问题主要在于你在findPerson函数中使用了addressBook的副本,而不是原始的addressBook对象。


在你的findPerson函数中,你传递的参数是addressBook的一个副本,而不是原始的addressBook对象。这意味着在函数内部,你实际上是在操作一个副本,而不是原始的addressBook对象。因此,当你试图使用指针访问abs->personArr[ret]时,编译器会报错,因为abs实际上是一个副本,而不是一个指针。


如果你想要在函数内部修改原始的addressBook对象,你需要传递一个指向addressBook的指针,而不是addressBook对象本身。这样,你就可以在函数内部通过指针访问和修改原始的addressBook对象。


这是一个修改后的代码示例:

void findPerson(addressBook* abs)
{
    string name;
    cout << "请输入要查找的联系人姓名:" << endl;
    cin >> name;

    int ret = detect(*abs, name);
    if (ret == -1)
    {
        cout << "没有找到联系人信息,请重新输入" << endl;
    }
    else
    {
        cout << "性别:" << abs->personArr[ret].sex << "\t"
            << "年龄:" << abs->personArr[ret].age << "\t"
            << "联系电话:" << abs->personArr[ret].number << "\t"
            << "住址:" << abs->personArr[ret].address << endl;
    }
    system("pause");
    system("cls");
}

注意,这里我们将函数的参数从addressBook abs更改为addressBook* abs,并在函数内部使用abs->personArr[ret]来访问和修改原始的addressBook对象。


该回答引用讯飞星火,仅为您提供参考,不保证完全正确
在这段代码中,使用指针的原因是为了在函数内部修改外部变量的值。当使用指针时,我们可以通过指针访问和修改原始数据结构的内容。在这个例子中,detect 函数接收一个 addressBook 类型的指针作为参数,这样我们就可以直接通过指针访问和修改 personArr 数组的内容。


如果不使用指针,我们需要将 addressBook 类型的变量的地址传递给函数,然后通过解引用指针来访问和修改数组的内容。这样做的缺点是,我们需要处理指针,这可能会导致更多的错误和复杂性。


在这个例子中,注释掉的部分使用了指针,而没有使用指针的部分则使用了数组索引。这是因为在 C++ 中,数组名实际上是一个指向数组第一个元素的指针。因此,当我们使用 abs.personArr[] 时,我们实际上是在使用指针。如果我们想要使用数组索引,我们需要将 addressBook 类型的变量强制转换为 addressBook* 类型,然后使用 -> 运算符。但是,这种做法并不推荐,因为它可能导致未定义的行为。

【以下回答由 GPT 生成】

我对优化后的代码没有其他问题需要解决。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^