我正在尝试使用例如指针打印数组的反面。输入为4 8 15 7,我想打印7 15 8 4。
当我运行它时,它会反转一些数字,但不是全部吗?有时它不会反转任何数字。我很困惑。
我需要它来处理数组中未知数量的元素,这就是为什么我在'readIntoArray'和'printArray'中使用while循环的原因。我真的只是在为“ reverseArray”和“ swap”而苦苦挣扎。
void reverseArray(double numbers[], int size);
void printArray(double numbers[], int size);
int readIntoArray(double numbers[]);
void swap(double *a, double *b);
int main(void) {
double numbers[MAX_SIZE];
int size = readIntoArray(numbers);
reverseArray(numbers, size);
printArray(numbers, size);
return 0;
}
int readIntoArray(double numbers[]) {
double in;
int i = 0;
while (i < MAX_SIZE && scanf("%lf", &in) != 0) {
numbers[i] = in;
i++;
}
return i;
}
void reverseArray(double numbers[], int size){
int x = 0;
double *a = &numbers[x];
double *b = &numbers[size - x];
double temp;
while (x < size){
swap(a,b);
x++;
}
}
void printArray(double numbers[], int size){
int i = 0;
while (i<size){
printf("%lf ", numbers[i]);
i++;
}
}
void swap (double *a, double *b){
int temp;
temp = *a;
*a = *b;
*b = temp;
}
我如何使其工作?我想念什么?
答案 0 :(得分:2)
您有很多明显的问题,但是主要的问题是您在swap
中使用了不同的类型大小,例如
void swap (double *a, double *b){
int temp;
temp = *a;
*a = *b;
*b = temp;
}
您要提供类型double
作为参数(通常为8个字节的值),但随后使用int temp;
(通常为4个字节的值)作为临时指针。因此,即使其他所有内容都正确,您也只会将*a
的前4个字节存储在temp
中。
接下来,如果您在整个范围0 < size
内进行反向操作,则最终将交换两次(返回到开始的位置)。相反,您希望在0 < size / 2
范围内交换每个结束元素。例如:
void reverseArray(double numbers[], size_t size){
for (size_t i = 0; i < size / 2; i++)
swap (&numbers[i], &numbers[size - i - 1]);
}
(注意:计数器通常应为size_t
而不是int
(您的行数不能为负)
此外,您需要修复scanf
验证。 scanf() != 0
允许scanf() = EOF
测试TRUE
,这显然不是您想要的。您可以针对转化说明符数量来验证返回值 ,例如
size_t readIntoArray(double numbers[]) {
double in;
size_t i = 0;
while (i < MAX_SIZE && scanf("%lf", &in) == 1) { /* <== here */
numbers[i] = in;
i++;
}
return i;
}
将其完全放入并重构代码以避免使用函数原型,您可以:
#include <stdio.h>
#define MAX_SIZE 128
size_t readIntoArray(double numbers[]) {
double in;
size_t i = 0;
while (i < MAX_SIZE && scanf("%lf", &in) == 1) {
numbers[i] = in;
i++;
}
return i;
}
void swap (double *a, double *b){
double temp;
temp = *a;
*a = *b;
*b = temp;
}
void reverseArray(double numbers[], size_t size){
for (size_t i = 0; i < size / 2; i++)
swap (&numbers[i], &numbers[size - i - 1]);
}
void printArray(double numbers[], size_t size){
int i = 0;
while (size--)
printf("%g ", numbers[i++]);
putchar ('\n');
}
int main(void) {
double numbers[MAX_SIZE] = { 0 };
size_t size = readIntoArray(numbers);
reverseArray (numbers, size);
printArray (numbers, size);
return 0;
}
使用/输出示例
$ echo "4 8 15 7" | ./bin/revarrswap
7 15 8 4
仔细研究一下,如果您有任何疑问,请告诉我。
答案 1 :(得分:1)
此代码:
double *a = &numbers[x];
double *b = &numbers[size - x];
double temp;
while (x < size){
swap(a,b);
x++;
}
从不更改a和b的值。即使您正在修改x,也已经将这些变量的第一个和最后一个元素的地址分配给了这些变量,然后将它们交换为所有x值。
一种更好的实现,应该可以实现您的预期目标:
for (unsigned i = 0; i != size/2; i++) {
swap(&numbers[i], &numbers[size-i-1]);
}
答案 2 :(得分:0)
#include <stdio.h>
void swap(double *a, double *b){
int temp;
temp = *a;
*a = *b;
*b = temp;
}
void reverse(double numbers[], int size) {
int half = size / 2;
for (int i = 0; i < half; i++) {
swap(numbers[i], numbers[size-1-i]);
}
}
int main() {
double ns[5] = {1,2,3,4,5};
reverse(ns, 5);
for (int i=0; i<5;i++) {
printf("%d\n", ns[i]);
}
return 0;
}
答案 3 :(得分:0)
查看reverseArray()
函数:
void reverseArray(double numbers[], int size){
int x = 0;
double *a = &numbers[x];
double *b = &numbers[size - x];
double temp;
while (x < size){
swap(a,b);
x++;
}
}
首先,在这里
double *b = &numbers[size - x];
您的代码正在访问超出其大小的数组。如果数组的大小为10
,则数组的有效索引为0
至9
,而size - x
会给您10
,因为在此时x
的值为0
。正在访问超出其大小的数组是undefined behavior。
在reverseArray()
函数中,您将numbers
数组的特定元素的地址分配给指针a
和b
,而不在{{1}内更改它们}循环。在循环的每次迭代中,while
函数最终都会交换相同的两个指针的值,并从这两个指针中换出一个,即指向数组之外。此外,该循环正在迭代swap()
次。相反,它应该仅迭代size
次。
size / 2
应该像这样:
reverseArray()
代码中还有其他问题,例如在void reverseArray(double numbers[], int size){
int x = 0;
while (x < size / 2){
swap(&numbers[x], &numbers[(size - 1) - x]);
x++;
}
}
函数中使用temp
类型的int
变量来交换swap()
类型的值,而不处理double
返回适当的等。@ David C. Rankin在他的帖子中对此进行了很好的解释。重申它们没有任何意义。