Изменение ** массива a на *массив[a]

#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]