【问题标题】:What necessitates the usage of the & operator while passing a structure through reference to a function?在通过对函数的引用传递结构时,需要使用 & 运算符吗?
【发布时间】:2021-09-13 16:33:02
【问题描述】:

我的查询相对简单。存在一个名为war_name 的结构,其定义如下:

struct war_name
{
    char name[40];
    char location[20];
    int deaths;
    int injuries;
    char victor_name[20];
    char loser_name[20];
};

我创建的上述结构的输入函数如下:

void enter_details(struct war_name *d)
{
    printf("\n________________________________________\n");
    printf("Enter the name of the battle: ");
    fgets(d->name,sizeof(d->name),stdin);
    printf("Enter the location: ");
    fgets(d->location,sizeof(d->location),stdin);
    printf("Enter the number of deaths: ");
    scanf("%d",&d->deaths);
    printf("Enter the number of injuries: ");
    scanf("%d",&d->injuries);
    printf("Enter the victor's name: ");
    fgets(d->victor_name,sizeof(d->victor_name),stdin);
    printf("Enter the defeated party's name: ");
    fgets(d->loser_name,sizeof(d->loser_name),stdin);
    printf("\n________________________________________\n");
}

现在,main() 部分具有以下组成:

int main(void)
{
    int n;
    printf("How many war details do you wish to input?\n");
    scanf("%d",&n);
    struct war_name *ptr=(struct war_name *)malloc(n*sizeof(struct war_name));
    if(ptr==NULL)
        printf("\nInitialization unsuccessful\n");
    for(int i=0;i<n;i++)
    {
        enter_details(ptr[i]);
    }
    exit(EXIT_SUCCESS);
}

此时有两个查询到达。

首先,当我将ptr 值直接传递给enter_details() 函数时,为什么我的编译器会吐出错误cannot convert 'war_name' to 'war_name*' for argument '1' to 'void enter_details(war_name*)'?为了验证仅将ptr[i] 传递给函数的假设会发送第 ith 结构的位置(这是函数所要求的),我直接打印了 ptr 的值,然后 lo 和看哪,该结构的地址被打印出来了。为什么尽管有这种发展,编译器会吐出错误并要求我使用 &amp; 运算符传递结构的地址,因为 ptr[i] 本身持有 ith 的值结构变量?

其次,关于ptr指针(指向结构war_name)的概念和malloc()的用法,是我用上述函数授予的可用空间初始化ptr的方式可以接受吗?为了参考起见,请注意,我所关注的书首先创建了一个指向 war_name 结构的数组指针,然后将所述结构的地址传递给函数?我的方法合理吗?考虑到我的方法节省了宝贵的内存,是否有必要构思一个指向上述结构的指针数组,然后将每个结构变量的地址传递给enter_details() 函数?

【问题讨论】:

  • ptr[i] 返回数组中第 i 个元素的值,而不是其地址
  • 展示比讲述要好。 “数组指针” 有点模棱两可,而且由于您(据您自己承认)仍在学习,因此您可能歪曲了您的教科书。
  • "将 ptr[i] 传递给函数会发送第 i 个结构的位置" ---> 不,ptr[i] 不是 第 i 个结构的位置。 ptr[i] 是第 i 个结构。 &amp;ptr[i] 是第 i 个结构的位置。
  • 错误:fgets() 将在scanf("%d",...); 之后读取剩余的'\n'。建议放弃 scanf() 使用。
  • 您可以使用fgets 后跟sscanf 来读取数字。另一个错误是fgets 将在字符串中存储换行符,因此如果用户输入bob 作为他们的名字,则结构中的name 数组将包含bob\n。有关如何删除换行符的建议,请参阅 stackoverflow.com/questions/2693776

标签: c struct


【解决方案1】:

正如 cmets 中所说,您的代码存在问题:


第一:

enter_details(ptr[i]);

错了。 enter_details() 接受指向 struct war_name 的指针,而 ptr[i] 的类型为 struct war_name。所以你应该做的是传递ptr[i]的地址:

enter_details(&ptr[i]);

其次,fgets() 读取最后一个\n,所以你应该用\0 替换它:

fgets(d->name, sizeof(d->name), stdin);
d->name[strcspn(d->name, "\n")] = '\0';

第三,你还应该避免使用scanf() 来读取整数。使用fgets(),然后使用sscanf()解析输入:

char buffer[255];
fgets(buffer, sizeof(buffer), stdin);
buffer[strcspn(buffer, "\n")] = '\0';

if (sscanf(buffer, "%d", &d->deaths) != 1)
    printf("Could not read int\n");

第四,

struct war_name *ptr=(struct war_name *)malloc(n*sizeof(struct war_name));

太长太冗长了。 You don't need to cast the return value of malloc() except if you use a C++ compiler:

struct war_name *ptr = malloc(n * sizeof(*ptr));

【讨论】:

  • 您不需要括号,sizeof *ptr,引用取消引用 &amp;ptr[i] 可以是 ptr + i。 (不是说你应该节省 2 个字节,而是你觉得更自然,或者由项目的样式指南决定。)
  • @LordObnoxious 不,你没有。让我们把它分成几部分: 1. struct war_name *ptr :你声明了一个指向 struct war_name 的指针(struct war_name 的数组) 2. = (struct war_name *):无用的转换(除非你使用 C++ 编译器) 3. @987654347 @:您正在分配 n 类型为 struct war_name 的元素。现在,当您编写 ptr[i] 时,您正在访问类型为 struct war_nameith 元素(参见第 3 点)。所以,ptr[i] 不是指针。因此,您需要将其地址传递给enter_details()
  • @LordObnoxious 是的,你可以。只需确保不要超出最后一个元素(超出范围),即始终计算 ++ 的数量。
  • 康德ptr = malloc(sizeof *ptr * n);
  • @LordObnoxious 对于 IDE:这确实是个人选择。我的建议是使用带有 C/C++ 扩展的 Visual Studio Code。它是一个多合一的编辑器,支持多种编程语言。但这只是我的建议。您可以自己尝试一下,看看哪种方法最适合您。
猜你喜欢
  • 2021-10-04
  • 1970-01-01
  • 2018-12-18
  • 2013-06-04
  • 1970-01-01
  • 1970-01-01
  • 2012-07-29
  • 2010-11-25
相关资源
最近更新 更多