У меня есть домашнее задание, с которым мне нужна помощь.
Я написал функцию, которая должна принимать пользовательский ввод с помощью 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;
}
Ошибка: в этой строке в основной функции
getVals(int ARRAYSIZE, int input[ARRAYSIZE]);
Правильный способ:
getVals(input, input[ARRAYSIZE]);
Во-первых: вы не должны использовать тип данных для своего атрибута при вызове функции.
Во-вторых: имя вашего массива является «входным», поскольку вы передаете массив, поэтому вы должны использовать имя массива, которое является входным, а не ARRAYSIZE...
Обратите внимание, что input[ARRAYSIZE]
в «исправленном» вызове обращается к значению за пределами массива. Если бы вы использовали ARRAYSIZE
в качестве второго аргумента для getVals()
— так что вы используете getVals(input, ARRAYSIZE);
— вы были бы в основном правы в одной из многих проблем в коде ОП.
Вы должны найти учебник. Они полны примеров кода, и вы можете контролировать, насколько простые вещи выполняются в них, когда вы не уверены.
Сначала ошибки.
Функция декларация просто объявляет функцию и ее аргументы. Вы используете его правильно. У вас может быть много объявлений для одной и той же функции в одной и той же программе, при условии, что все они согласованы.
Функция определение содержит код функции. Программа должна содержать ровно одно определение для каждой функции. Кстати, определение также является объявлением
Вызов функции — это место, где функция используется. Это больше не объявление, и объявление функции должно быть видно перед вызовом. Вы должны передать существующие переменные в соответствии с объявлением.
Здесь у вас должно быть:
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: ответственность за размер переданного буфера должна лежать на вызывающем, а не на вызываемом объекте. И в основном я передаю ARRAYSIZE
за формальный параметр maxVals
.
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
как глобальную переменную, но в этом нет необходимости. По возможности следует избегать глобальных переменных (переменных, определенных вне какой-либо функции).
Это имеет отношение к вашей проблеме, но… —— Обратите внимание, что строка
int input[ARRAYSIZE+1] = {'0'};
инициализируетinput[0]
значением48
и оставляет все остальные элементы равными 0. Вы должны писать0
, а не'0'
, когда имеете в виду ноль. Технически вы могли бы использовать'\0'
и получить результат «все нули», но это было бы своеобразным выбором обозначения и довольно опрометчивым. Используйте'\0'
при работе с персонажами; используйте0
, когда вы работаете с целыми числами.