#c #arrays #pointers
#c #массивы #указатели
Вопрос:
Что делает моя программа, так это находит 2 числа массива, которые ближе всего к среднему, одно больше, другое меньше. Это работает нормально, однако мне нужно изменить, например, **array a
на *array[a]
.
Однако, когда я загружаю программу, она вылетает после ввода чисел. Если я попытаюсь напечатать *array[0]
, *array[1]
и т.д. все работает нормально. Когда я пытаюсь напечатать или просто что-то сделать с *array[a]
, *array[b]
происходит сбой. Спасибо за вашу помощь.
#include <stdio.h>
#include <stdlib.h>
int input (int *t, int *array[]);
void calculation (int *array[], int *t, int *x, int *y);
void output (int *x, int *y);
int main()
{
int *array, t, x, y;
input (amp;t, amp;array);
calculation (amp;array, amp;t, amp;x, amp;y);
output (amp;x, amp;y);
return 0;
}
int input (int *t, int *array[])
{ int n, *ptr;
printf ("How big is the array?");
scanf ("%d", amp;n);
ptr = (int*) malloc(n * sizeof(int));
int k;
printf ("Enter the numbers:");
for (k=0; k<n; k )
{ scanf ("%d", ptr k);
}
*t=n;
*array=ptr;
return 0;
}
void calculation (int *array[], int *t, int *x, int *y)
{ float sum=0, avg;
int min, max;
int more, less;
int a, b, c;
for (a=0; a<(*t); a )
{sum=sum **array a;
}
avg=sum/(*t);
min= *array[0];
max= *array[0];
for (b=0; b<(*t); b )
{ if (max < (**array b)) max=(**array b);
if (min > (**array b)) min=(**array b);
}
more=max;
less=min;
for (c=0; c<(*t); c )
{ if (((**array c) < avg) amp;amp; ((**array c) > less)) less=(**array c);
if (((**array c) > avg) amp;amp; ((**array c) < more)) more=(**array c);
}
*x=less;
*y=more;
}
void output (int *x, int *y)
{ printf("Number that is less than the average:%dn", *x);
printf("Number that is more than the average:%dn", *y);
}
Комментарии:
1.
**array a
Для(*array)[a]
2. В объявлении
int *array[]
говорится, чтоarray
это массив указателей, а не указатель на массив.3. Работает отлично! Спасибо. 🙂
4. Я не могу поверить, что ваш код работает правильно, как есть в вопросе. Когда я запускаю его с ’10 20 30` в качестве входного массива, он выводит
Number that is less than the average:10 Number that is more than the average:12
. Это:sum=sum **array a;
почти наверняка должно быть:sum=sum *(*array a);
. Кажется, вы ожидаете, что один из них*
будет привязан сильнее, чем, а другой — нет…
5. (Обратите внимание, что
*(*array a)
это эквивалентно(*array)[a]
.**array a
не может быть записан в виде массива).
Ответ №1:
Было бы лучше немного переосмыслить прототипы ваших функций. Имеет смысл передать указатель на array
на input()
функцию, поскольку вы выделяете для нее память и хотите иметь к ней доступ при возвращении. Но вам не нужно передавать указатель на int t
; вместо этого просто верните значение n
и присвоите его t
в main.
Нет причин передавать указатель на array
функцию calculation()
, поскольку вы не изменяете распределение массива. Вы также можете передать значение t
из main()
, поскольку вы используете это значение только в calculation()
, но не изменяете его.
Аналогично, output()
функции нужны только копии x
и y
, поскольку она их не изменяет.
Эмпирическое правило здесь заключается в том, что вы передаете указатель на значение в функцию, когда хотите изменить значение внутри функции и получить доступ к измененному значению в вызывающей функции. Но вы также можете возвращать значение вместо использования указателя на него.
Эти изменения не изменяют функциональность вашего кода, но они существенно улучшают его читаемость. Вы даже получаете представление о том, что изменяется в каждой функции, просто взглянув на прототипы функций. Что ж, изменения действительно изменяют функциональность в том смысле, что ваш оригинал **array a
был неправильным и должен был быть либо *(*array a)
, либо (*array)[a]
. Но решение этой проблемы должно помочь вам оценить преимущества более простых прототипов функций. Вот измененный код:
#include <stdio.h>
#include <stdlib.h>
int input(int *array[]);
void calculation(int array[], int t, int *x, int *y);
void output(int x, int y);
int main(void)
{
int *array, t, x, y;
t = input(amp;array);
calculation(array, t, amp;x, amp;y);
output(x, y);
return 0;
}
int input(int *array[])
{ int n, *ptr;
printf("How big is the array?");
scanf("%d", amp;n);
ptr = (int*) malloc(n * sizeof(int));
int k;
printf("Enter the numbers:");
for (k=0; k<n; k )
{ scanf("%d", ptr k);
}
*array=ptr;
return n;
}
void calculation(int array[], int t, int *x, int *y)
{ float sum=0, avg;
int min, max;
int more, less;
int a, b, c;
for (a=0; a<t; a )
{sum=sum array[a];
}
avg=sum/t;
min= array[0];
max= array[0];
for (b=0; b<t; b )
{ if (max < array[b]) max=array[b];
if (min > array[b]) min=array[b];
}
more=max;
less=min;
for (c=0; c<t; c )
{ if ((array[c] < avg) amp;amp; (array[c] > less)) less=array[c];
if ((array[c] > avg) amp;amp; (array[c] < more)) more=array[c];
}
*x=less;
*y=more;
}
void output(int x, int y)
{ printf("Number that is less than the average:%dn", x);
printf("Number that is more than the average:%dn", y);
}
Комментарии:
1. Конечно,
*(*array a)
(не(**array a)
) эквивалентно(*array)[a]
. Или мой мозг действительно сегодня работает неправильно?2. Я зашел так далеко, что проверил это; Я совершенно уверен, что исходная программа OP неверна (несмотря на их утверждение об обратном), и это не правильно, что
*(*array a)
эквивалентно**array a
. Вы говорите, что это**arr
указывает на первый элемент массива, но на самом деле это является первым элементом массива —*arr
указывает на первый элемент массива — верно? Таким образом,**arr i
фактически значение первого элемента в массиве плюсi
, а не значениеi
-го элемента.3. @davmac — Вы правы! Я ломал голову над этим, даже когда вы отправляли комментарий. На самом деле мой ответ был не об эквивалентности выражений, поэтому я не придал этому большого значения. Я запустил программу OPs, и, похоже, она сработала. Но я только сейчас попробовал со значениями 3 1 4 1 5 9, и операционная версия выдала результаты 5 и 6! Моя версия (которая все еще может быть неправильной, потому что я изменил только прототипы функций) дала правильный результат 3 и 4. Хороший улов.
4. @davmac — Я не знаю, как я пропустил ваши предыдущие комментарии к OP. Я удалю эту глупость из своего ответа и facepalm….
5. Нет проблем — я думал, что немного схожу с ума, рад узнать, что это не так!
Ответ №2:
Как и сказали BLUEPIXY и какой-то чувак-программист, это должно быть (*array)[a]