在函数中使用 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]
不是有效的指针,它甚至可能未初始化(因此具有 不确定的 值)你将有 未定义的行为 .
所以我有一个指针和数组的大小,它们被传递给一个函数,该函数要求用户输入并将用户输入存储为数组元素。
所以函数看起来像这样:
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]
不是有效的指针,它甚至可能未初始化(因此具有 不确定的 值)你将有 未定义的行为 .