在函数中使用 scanf 输入更新数组元素(使用指针访问)

Update array elements (access using pointers) using scanf inputs in function

所以我有一个指针和数组的大小,它们被传递给一个函数,该函数要求用户输入并将用户输入存储为数组元素。

所以函数看起来像这样:

int addElements(int * ptr, int sizeArr) {

int k=0;
for (k=0; k<=size; k++) {
    printf("please enter element number %d\n", k);
    scanf("%d", *(ptr+k));
}

return pArr;

}

它 returns 是一个指针,因为我需要进一步处理数组。

我明白了

Segmentation fault (Core dumped)

向数组输入元素时出错。

我在这里做错了什么?我可以将数组元素(从 random/automatic 值)更新为 0 就好了,只是无法写入数组的 scanf。

ptr 是指向 int.

的指针

(ptr + k) 仍然是指向(不同的)int 的指针。 *(ptr + k) 是一个 int.

scanf( "%d", <some_int> ) 会将存储在 int 中的 number 解释为地址 ,并尝试写入无论用户输入什么 "address".

这是未定义的行为。

您可能想省略 * 将指针变成 int;那么该语句就是合式的。

总的来说,推荐阅读.

  • 检查 scanf() 的 return 值,因为用户输入的内容可能不是数字。
  • 通过读取下一个换行符来满足仍在输入缓冲区中等待的非数字输入,否则后续 scanf( "%d", ... ) 也会失败。
  • 更好的是,读取输入的 (使用 fgets()),并在内存中解析它们(使用 strtol()),这样您就可以更优雅地从错误输入中恢复。

通过更改

修改您阅读元素的方式
scanf("%d", *(ptr+k));

scanf("%d", (ptr+k));

Scanf 需要在说明符旁边有一个指针,但是 ptr 已经是一个指针( ptr+k 也是)所以通过使用星号你暗示指针的内容而不是指针本身。

对于任何指针(或数组)pArr 和索引 k,表达式 *(pArr + k) 等同于 pArr[i].

问题在于 pArr[i](因此 *(pArr + k))不是指针,而 scanf 需要它才能工作。

有两个解决方案:第一个是继续使用指针运算,然后简单地删除解引用运算符(这样你只将 pArr + k 传递给 scanf);或者您使用 "normal" 数组索引并添加地址运算符(如 &pArr[k])。


关于备选方案的一些解释。表达式 pArr[k] 为您提供数组中索引 k 处的值,为了获得指向该值的指针,我们添加地址运算符 & 并获得 &pArr[k].

并且由于 pArr[k] 等同于 *(pArr + k),因此 &pArr[k] 将等同于 &*(pArr + k),但是寻址运算符和取消引用运算符相互抵消了你pArr + k.


问题中显示的代码现在发生的情况是,您在索引 k 处获取值(即 pArr[k]),编译器将其转换为指针(它应该给出你虽然警告它)然后 scanf 写入该值指向的内存。由于 pArr[k] 不是有效的指针,它甚至可能未初始化(因此具有 不确定的 值)你将有 未定义的行为 .