Вызов функции, которая хранит целые числа в массиве в C

У меня есть домашнее задание, с которым мне нужна помощь.

Я написал функцию, которая должна принимать пользовательский ввод с помощью scanf и сохранять его в массив. Он также будет подсчитывать, сколько раз вводится целое число (кроме 0, что завершает программу). У меня конкретно возникла проблема с вызовом этой функции в main() Любые предложения о том, как это исправить?

Я пытался использовать определение функции внизу и использовать разные переменные внутри функции: getVals

#include <stdio.h>

#define ARRAYSIZE 20 //defines the size of the array to 20

int nVals = 0;
int getVals(int myVals[], int maxVals);
int input[ARRAYSIZE+1] = {'0'};

int getVals(int myVals[], int maxVals)
{
  for (maxVals = 0; maxVals < ARRAYSIZE; maxVals++) { //When the row is    less than ten, it will run the loop and increment the row
    printf("Please Enter up to 20 integers "); //which will allow the name to be stored in the next row
    scanf("%d", &myVals[maxVals]);

    if ((myVals[maxVals] <= 0) || (maxVals == ARRAYSIZE -1))
       return nVals;
    if (myVals[maxVals] > 0)
       nVals++;

  }
}

int main() {
  printf("This program will receive up to 20 inputs from you, and sort them from least to greatest\n\n");
  printf("Enter 0 or a negative number to exit the program.\n");

  getVals(int ARRAYSIZE, int input[ARRAYSIZE]);

  printf("You have entered %d numbers\n", nVals);
  printf("%d", input[]);
  printf("\n");
  printf("Now sorting....\n");

  return 0;
}

Это имеет отношение к вашей проблеме, но… —— Обратите внимание, что строка int input[ARRAYSIZE+1] = {'0'}; инициализирует input[0] значением 48 и оставляет все остальные элементы равными 0. Вы должны писать 0, а не '0', когда имеете в виду ноль. Технически вы могли бы использовать '\0' и получить результат «все нули», но это было бы своеобразным выбором обозначения и довольно опрометчивым. Используйте '\0' при работе с персонажами; используйте 0, когда вы работаете с целыми числами.

Jonathan Leffler 28.05.2019 07:58
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
1
793
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ошибка: в этой строке в основной функции

getVals(int ARRAYSIZE, int input[ARRAYSIZE]);

Правильный способ:

getVals(input, input[ARRAYSIZE]);

Во-первых: вы не должны использовать тип данных для своего атрибута при вызове функции.

Во-вторых: имя вашего массива является «входным», поскольку вы передаете массив, поэтому вы должны использовать имя массива, которое является входным, а не ARRAYSIZE...

Обратите внимание, что input[ARRAYSIZE] в «исправленном» вызове обращается к значению за пределами массива. Если бы вы использовали ARRAYSIZE в качестве второго аргумента для getVals() — так что вы используете getVals(input, ARRAYSIZE); — вы были бы в основном правы в одной из многих проблем в коде ОП.

Jonathan Leffler 28.05.2019 08:37
Ответ принят как подходящий

Вы должны найти учебник. Они полны примеров кода, и вы можете контролировать, насколько простые вещи выполняются в них, когда вы не уверены.

Сначала ошибки.

Функция декларация просто объявляет функцию и ее аргументы. Вы используете его правильно. У вас может быть много объявлений для одной и той же функции в одной и той же программе, при условии, что все они согласованы.

Функция определение содержит код функции. Программа должна содержать ровно одно определение для каждой функции. Кстати, определение также является объявлением

Вызов функции — это место, где функция используется. Это больше не объявление, и объявление функции должно быть видно перед вызовом. Вы должны передать существующие переменные в соответствии с объявлением.

Здесь у вас должно быть:

int input[ARRAYSIZE];          // declare an int array
getVals(input, ARRAYSIZE);     // call the function

Эта строка printf("%d", input[]); тоже неверна. Массивы не являются гражданами первого класса в языке C, и вы можете печатать (или читать) только один элемент за раз. По крайней мере, вы должны написать printf("%d", input); (это вызов, а не объявление, поэтому требуются фактические параметры, а не формальные). Но массив распадется на указатель на его первый элемент (хорошо, пока там), указатель будет преобразован в значение int (адрес первого элемента массива), и вы напечатаете это значение. Не то, что вы хотите :-(

Но есть и другие возможные улучшения.

nVal — глобальное значение. Следует избегать глобальных переменных, если у вас нет веских причин для их создания. Передовой опыт рекомендует вместо этого передавать параметры в функцию. Поэтому вы должны удалить gloval int nVals = 0 изменить getVals на:

int getVals(int myVals[], int maxVals)
{
    int nVals;
    for (nVals = 0; nVals < maxVals; nVals++) { //When the row is    less than ten, it will run the loop and increment the row
        printf("Please Enter up to 20 integers "); //which will allow the name   to be stored in the next row
        if (1 != scanf("%d", &myVals[nVals])) {    // ALWAYS test scanf return value
            printf("Incorrect input");
            break;
        }
        if (myVals[nVals] <= 0) {
            break;
        }
    }
    return nVals;
}

и вызовите его из основного как:

int nVals = getVals(input, ARRAYSIZE);

Спасибо за ваш ответ! Я сделал некоторые настройки, и функция работает. Еще один конкретный вопрос: зачем мне заменять ARRAYSIZE в цикле на maxVals, если мне нужно всего до 20 входов? maxVals не определяется как 20, как ARRAYSIZE.

TRADEMARKsage 28.05.2019 18:33

@TRADEMARKsage: ответственность за размер переданного буфера должна лежать на вызывающем, а не на вызываемом объекте. И в основном я передаю ARRAYSIZE за формальный параметр maxVals.

Serge Ballesta 28.05.2019 19:18

Проблема в main()

Как отметили Риши в своем отвечать, одна строка с ошибкой — это строка в main():

getVals(int ARRAYSIZE, int input[ARRAYSIZE]);

Это должно предотвратить компиляцию вашего кода, потому что после завершения препроцессора строка выглядит так:

getVals(int 20, int input[20]);

Это вообще недопустимо для C — первая 20 — бессмысленная синтаксическая ошибка.

Предполагая, что у вас есть что-то, что более или менее компилируется, например, одно из этих:

getVals(int SIZE, int input[ARRAYSIZE]);
getVals(int SIZE, int input[SIZE]);

тогда у вас есть объявление функции без возвращаемого типа. По правилам C90 это не могло появиться в середине функции. В соответствии с правилами C99 или более поздних версий он может появляться там, где он есть, но он должен иметь возвращаемый тип —

int getVals(int SIZE, int input[ARRAYSIZE]);
int getVals(int SIZE, int input[SIZE]);

Первое из объявлений действительно как в C90, так и в C99, хотя ARRAYSIZE не имеет значения. Второе из объявлений допустимо только в C99 или более поздней версии, поскольку оно использует VLA (массив переменной длины). Таких не было в C90.

Однако, поскольку это объявление, а не вызов функции, фактическая функция getVals() никогда не вызывается, что является проблемой, о которой вы сообщили.

Вы на самом деле хотите:

int num = getVals(ARRAYSIZE, input);

Кроме:

Вы определили getVals(), используя:

int getVals(int myVals[], int maxVals)

поэтому вам действительно нужно вызвать:

getVals(input, ARRAYSIZE);

Проблемы в getVals()

С этой функцией тоже бардак. Вероятно, вам следует использовать что-то вроде:

int getVals(int myVals[], int maxVals)
{
    int i;
    for (i = 0; i < maxVals; i++)
    {
        printf("Please Enter up to 20 integers ");
        if (scanf("%d", &myVals[i]) != 1)
            return i;
        if (myVals[i] <= 0)
            return i;
        nVals++;
    }
    return i;
}

Я сохранил nVals как глобальную переменную, но в этом нет необходимости. По возможности следует избегать глобальных переменных (переменных, определенных вне какой-либо функции).

Другие вопросы по теме