Error c2561 main функция должна возвращать значение

C++ Documentation. Contribute to MicrosoftDocs/cpp-docs development by creating an account on GitHub.
description title ms.date f1_keywords helpviewer_keywords ms.assetid

Learn more about: Compiler Error C2561

Compiler Error C2561

11/04/2016

C2561

C2561

0abe955b-53a6-4a3c-8362-b1a8eb40e8d1

Compiler Error C2561

‘identifier’ : function must return a value

The function was declared as returning a value, but the function definition does not contain a return statement.

This error can be caused by an incorrect function prototype:

  1. If the function does not return a value, declare the function with return type void.

  2. Check that all possible branches of the function return a value of the type declared in the prototype.

  3. C++ functions containing inline assembly routines that store the return value in the AX register may need a return statement. Copy the value in AX to a temporary variable and return that variable from the function.

The following sample generates C2561:

// C2561.cpp
int Test(int x) {
   if (x) {
      return;   // C2561
      // try the following line instead
      // return 1;
   }
   return 0;
}

int main() {
   Test(1);
}
description title ms.date f1_keywords helpviewer_keywords ms.assetid

Learn more about: Compiler Error C2561

Compiler Error C2561

11/04/2016

C2561

C2561

0abe955b-53a6-4a3c-8362-b1a8eb40e8d1

Compiler Error C2561

‘identifier’ : function must return a value

The function was declared as returning a value, but the function definition does not contain a return statement.

This error can be caused by an incorrect function prototype:

  1. If the function does not return a value, declare the function with return type void.

  2. Check that all possible branches of the function return a value of the type declared in the prototype.

  3. C++ functions containing inline assembly routines that store the return value in the AX register may need a return statement. Copy the value in AX to a temporary variable and return that variable from the function.

The following sample generates C2561:

// C2561.cpp
int Test(int x) {
   if (x) {
      return;   // C2561
      // try the following line instead
      // return 1;
   }
   return 0;
}

int main() {
   Test(1);
}

Содержание

  1. Ошибки компилятора с C2500 по C2599
  2. Функция main. Аргументы и возвращаемое значение
  3. 2.2 – Возвращаемые значения функций
  4. Возвращаемые значения
  5. Исправляем нашу тестовую программу
  6. Отсутствие возвращаемого значения
  7. Возвращаясь к main
  8. Несколько дополнительных замечаний о возвращаемых значениях
  9. Повторное использование функций
  10. Заключение
  11. Небольшой тест

Ошибки компилятора с C2500 по C2599

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

Компиляторы и средства сборки Visual Studio могут сообщать о различных типах ошибок и предупреждений. После обнаружения ошибки или предупреждения средства сборки могут делать предположения о намерении кода и пытаться продолжить работу, чтобы можно было сообщать о дополнительных проблемах одновременно. Если средства делают неверное предположение, последующие ошибки или предупреждения не могут применяться к проекту. При устранении проблем в проекте всегда начинайте с первой зарегистрированной ошибки (или предупреждения) и выполняйте повторную сборку как можно чаще. Одно исправление может привести к возникновению многих последующих ошибок.

Чтобы получить справку о конкретном диагностическом сообщении в Visual Studio, выберите его в окне вывода и нажмите клавишу F1 . Visual Studio открывает страницу документации для этой ошибки, если она существует. Вы также можете использовать средство поиска в верхней части страницы, чтобы найти статьи о конкретных ошибках или предупреждениях. Кроме того, просмотрите список ошибок и предупреждений по инструменту и введите оглавление на этой странице.

Не все ошибки или предупреждения Visual Studio описаны. Во многих случаях диагностическое сообщение предоставляет все доступные сведения. Если вы приземлились на этой странице при использовании F1 и считаете, что сообщение об ошибке или предупреждении требует дополнительного объяснения, сообщите нам об этом. Кнопки обратной связи на этой странице можно использовать для создания проблемы с документацией на сайте GitHub. Если вы считаете, что ошибка или предупреждение неправы или обнаружена другая проблема с набором инструментов, сообщите о проблеме с продуктом на сайте Сообщество разработчиков. Вы также можете отправить отзыв и ввести ошибки в интегрированной среде разработки. В Visual Studio перейдите в строку меню и выберите «Отправить > отзыв справки>» или отправьте предложение с помощью отправки > отзывов > справки.

Вы можете найти дополнительную помощь по ошибкам и предупреждениям на форумах Microsoft Learn Q&A . Или найдите номер ошибки или предупреждения на сайте Сообщество разработчиков Visual Studio C++. Вы также можете выполнить поиск решений в Stack Overflow .

Ссылки на дополнительные справочные материалы и ресурсы сообщества см. в справке и сообществе Visual C++.

Источник

Функция main. Аргументы и возвращаемое значение

У функции main() в языке С++ есть два аргумента — argc и argv , кроме того она возвращает целое число. Почему в качестве возвращаемого значения обычно используют ноль, но часто вообще ничего не возвращают (и компилятор не ругается)? Зачем все это нужно и почему часто эту функцию используют без аргументов?

Аргументы функции main используются для передачи данных в приложение через командную строку или от других приложений. Эту технологию используют все системные утилиты в любой операционной системе, а также, например, инструменты программиста (компилятор, отладчик, компоновщик и т.п.). Чтобы скомпилировать файл main.cpp — вы можете написать:
g++ main.cpp -o main
При этом запустится программа g++ (в Windows g++.exe ) и ей на вход будет передано три аргумента — «main.cpp» , «-o» , «main» . Программа анализирует не только сами аргументы, но и их порядок.

Итак, у функции main() может быть два аргумента — первый отвечает за количество полученных параметров (обычно называют argc ), а второй представляет собой массив параметров ( argv ). Вне значения, переданные в программу, внутри рассматриваются как символьные строки — тип argv — char*[argc+1] .

Даже если не передавать программе никаких значений — argc будет равен единице, т.к. argv[0] всегда содержит имя запущенной программы. Последний элемент массива параметров ( argv[argc] ) всегда равен нулю — это может использоваться при переборе параметров.

Часто делают так, что при запуске программы без аргументов она начинает диалог с пользователем, но если аргументы переданы — то использует их (не задает лишних вопросов):

Приведенная программа выводит на экран первое число из файла. При этом если имя файла передается в качестве аргумента, но если аргумент не задан — программа спросит требуемое имя у пользователя во время работы:

На снимке экрана используется стандартная в UNIX команда cat , выводящая на экран содержимое файла.

Многие утилиты требуют определенное количество входных аргументов, например если приложение на вход всегда должно принимать входной и выходной файл — программа может для начала проверить количество параметров:

Программа может перебирать аргументы как элементы массива, однако зачастую пользователь передает в качестве значений числа — преобразовать строку в число можно, например, с помощью sscanf или std::stringstream .

В последнем примере функция main() возвращает значение. Значением всегда является целое число, которое обрабатывается операционной системой — процесс, завершающийся с кодом ноль отработал без ошибок, во всех остальных случаях операционная система знает что произошла какая-то ошибка (при этом значения могут быть любыми, на них нет никакого стандарта). Нулевое значение функция main() вернет автоматически (при нормальном завершении программы) — это зафиксировано стандартом языка, все остальные значения рекомендуется именовать при помощи констант или перечислений ( enum ).

Источник

2.2 – Возвращаемые значения функций

Рассмотрим следующую программу:

Эта программа состоит из двух концептуальных частей: во-первых, мы получаем значение от пользователя. Затем мы сообщаем пользователю, чему равно это значение, умноженное на два.

Хотя эта программа достаточно тривиальна, и нам не нужно разбивать ее на несколько функций, но что, если бы мы захотели это сделать? Получение целочисленного значения от пользователя – это четко определенная задача, которую мы хотим, чтобы наша программа выполняла, поэтому она могла бы стать хорошим кандидатом на функцию.

Итак, давайте напишем программу для этого:

Хотя эта программа – хорошая попытка решения, она не совсем работает.

Когда вызывается функция getValueFromUser , пользователя просят ввести целое число, как и ожидалось. Но введенное им значение теряется, когда getValueFromUser завершает работу и управление возвращается к main . Переменная num никогда не инициализируется значением, введенным пользователем, поэтому программа всегда печатает ответ 0.

Чего нам не хватает, так это того, чтобы getValueFromUser могла вернуть значение, введенное пользователем, обратно в main , чтобы main могла использовать эти данные.

Возвращаемые значения

Когда вы пишете пользовательскую функцию, вы можете определить, будет ли ваша функция возвращать значение вызывающей стороне или нет. Чтобы вернуть значение вызывающей стороне, необходимы две вещи.

Во-первых, ваша функция должна указать, значение какого типа будет возвращено. Это делается путем установки типа возвращаемого значения функции, который является типом, определенным перед именем функции. В приведенном выше примере функция getValueFromUser имеет тип возвращаемого значения void , а функция main имеет тип возвращаемого значения int . Обратите внимание, что это не определяет, какое конкретное значение будет возвращено – только тип значения.

Во-вторых, внутри функции, которая будет возвращать значение, мы используем инструкцию return , чтобы указать конкретное значение, возвращаемое вызывающей стороне. Конкретное значение, возвращаемое функцией, называется возвращаемым значением. Когда инструкция return выполняется, возвращаемое значение копируется из функции обратно в вызывающую функцию. Этот процесс называется возвратом по значению.

Давайте рассмотрим простую функцию, которая возвращает целочисленное значение, и пример программы, которая ее вызывает:

При запуске эта программа печатает:

Выполнение начинается с верхней части main . В первой инструкции вычисляется вызов функции returnFive , в результате чего вызывается функция returnFive . Функция returnFive возвращает конкретное значение 5 обратно вызывающей стороне, которое затем выводится в консоль через std::cout .

Во второй инструкции вычисляется вызов функции returnFive , что приводит к повторному вызову функции returnFive . Функция returnFive возвращает значение 5 обратно вызывающей стороне. Выражение 5 + 2 вычисляется для получения результата 7, который затем выводится в консоль через std::cout .

В третьей инструкции функция returnFive вызывается снова, в результате чего значение 5 возвращается обратно вызывающей стороне. Однако функция main ничего не делает с возвращаемым значением, поэтому больше ничего не происходит (возвращаемое значение игнорируется).

Примечание. Возвращаемые значения не будут напечатаны, если вызывающая функция не отправит их в консоль через std::cout . В последнем случае, в примере выше, возвращаемое значение не отправляется в std::cout , поэтому ничего не печатается.

Исправляем нашу тестовую программу

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

Когда эта программа выполняется, первая инструкция в main создаст переменную типа int с именем num . Когда программа перейдет к инициализации num , она увидит, что есть вызов функции getValueFromUser , поэтому она выполнит эту функцию. Функция getValueFromUser просит пользователя ввести значение, а затем возвращает это значение вызывающей функции ( main ). Это возвращенное значение используется как значение для инициализации переменной num .

Скомпилируйте эту программу и запустите ее несколько раз, чтобы убедиться, что она работает.

Отсутствие возвращаемого значения

Функции не обязаны возвращать значение. Чтобы сообщить компилятору, что функция не возвращает значение, используется тип возвращаемого значения void . Давайте посмотрим на функцию doPrint() из предыдущего урока:

Эта функция имеет тип возвращаемого значения void , что указывает на то, что она не возвращает значение вызывающей стороне. Поскольку она не возвращает значение, инструкция return не требуется (попытка вернуть конкретное значение из функции с типом возврата void приведет к ошибке компиляции).

Вот еще один пример функции, ничего не возвращающей, и пример программы, которая ее вызывает:

При первом вызове функции returnNothing функция печатает « Hi », а затем ничего не возвращает вызывающей функции. Управление возвращается в main , и программа продолжает выполнение.

Второй вызов функции returnNothing даже не будет компилироваться. Функция returnNothing имеет возвращаемый тип void , то есть не возвращает значения. Однако эта инструкция пытается отправить возвращаемое из returnNothing значение в std::cout для печати. std::cout не знает, что с этим делать (какое значение он будет выводить?). Следовательно, компилятор пометит это как ошибку. Вам нужно закомментировать эту строку кода, чтобы код компилировался.

Тип возврата void (что означает, что ничего не возвращается) используется, когда нам нужна функция, которая ничего не возвращает вызывающей стороне (потому что в этом нет необходимости). В приведенном выше примере у функции returnNothing есть полезное поведение (она печатает « Hi »), но ей не нужно ничего возвращать вызывающей стороне (в данном случае main ). Следовательно, функции returnNothing присваивается возвращаемый тип void .

Возвращаясь к main

Теперь у вас есть концептуальные инструменты, чтобы понять, как на самом деле работает функция main . Когда программа выполняется, операционная система вызывает функцию main . Затем выполнение переходит в начало main . Инструкции в main выполняются последовательно. Наконец, main возвращает целочисленное значение (обычно 0), и ваша программа завершается. Значение, возвращаемое из main , иногда называют кодом состояния (также иногда называемым кодом выхода или, реже, кодом возврата), поскольку оно используется, чтобы указать, успешно ли была выполнена программа.

По определению, код состояния 0 означает, что программа выполнена успешно.

Лучшая практика

Ваша функция main должна возвращать 0, если программа работает нормально.

Код состояния, отличный от нуля, часто используется для обозначения сбоя (и хотя он отлично работает в большинстве операционных систем, строго говоря, его портируемость не гарантируется).

Для продвинутых читателей

Стандарт C++ определяет значение только трех кодов состояния: 0, EXIT_SUCCESS и EXIT_FAILURE . 0 и EXIT_SUCCESS означают, что программа выполнена успешно. EXIT_FAILURE означает, что программа не была успешно выполнена.

EXIT_SUCCESS и EXIT_FAILURE определены в заголовочном файле :

Если вы хотите максимизировать портируемость, вы должны использовать только 0 или EXIT_SUCCESS , чтобы указать на успешное завершение, или EXIT_FAILURE , чтобы указать на неудачное завершение.

C++ запрещает явный вызов функции main .

На данный момент вы также должны определять свою функцию main внизу исходного файла кода, под другими функциями.

Несколько дополнительных замечаний о возвращаемых значениях

Во-первых, если функция имеет тип возврата, являющийся не- void , она должна возвращать значение этого типа (используя инструкцию return ). Несоблюдение этого правила приведет к неопределенному поведению. Единственное исключение из этого правила – функция main() , которая, если возвращаемое значение не указано явно, примет, что оно равно 0. Тем не менее, рекомендуется явно возвращать значение из main , как для демонстрации вашего намерения, так и для согласованности с другими функциями (что не позволит вам опустить возвращаемое значение).

Лучшая практика

Всегда явно указывайте возвращаемое значение для любой функции, которая имеет тип возврата не- void .

Предупреждение

Неспособность вернуть значение из функции с типом возврата не- void (кроме main ) приведет к неопределенному поведению.

Во-вторых, когда выполняется инструкция return , функция немедленно, в этой точке, возвращается в вызывающую функцию. Любой дополнительный код в функции игнорируется.

В-третьих, функция может возвращать вызывающей функции при каждом вызове только одно значение. Однако это значение не обязательно должно быть литералом, оно может быть результатом любого допустимого выражения, включая переменную или даже вызов другой функции, которая возвращает значение. В приведенном выше примере getValueFromUser() мы вернули переменную, содержащую число, введенное пользователем.

Наконец, обратите внимание, что функция может определять, что означает ее возвращаемое значение. Некоторые функции используют возвращаемые значения как коды состояния, чтобы указать, были ли они успешными или неудачными. Другие функции возвращают вычисленное или выбранное значение. Остальные функции ничего не возвращают. Что возвращает конкретная функция, и смысл этого значения определяется автором функции. Из-за большого разнообразия возможностей рекомендуется задокументировать функцию комментарием, указывающим, что означают возвращаемые значения.

Повторное использование функций

Теперь мы можем проиллюстрировать хороший случай повторного использования функции. Рассмотрим следующую программу:

Пока эта программа работает, но она немного избыточна. Фактически, эта программа нарушает один из основных принципов хорошего программирования: «Не повторяйся» (или англоязычная аббревиатура DRY, т.е. «Don’t Repeat Yourself»).

Почему повторяющийся код плох? Если бы мы хотели изменить текст « Enter an integer: » на что-то другое, нам пришлось бы обновить его в двух местах. А что, если бы мы захотели инициализировать 10 переменных вместо 2? Это было бы большое количество избыточного кода (что сделало бы наши программы длиннее и сложнее для понимания) и много места для вкрадывания опечаток.

Давайте обновим эту программу, чтобы использовать нашу функцию getValueFromUser , которую мы разработали выше:

Эта программа создает следующий вывод:

В этой программе мы дважды вызываем getValueFromUser : один раз для инициализации переменной x и один раз для инициализации переменной y . Это избавляет нас от дублирования кода для ввода пользовательских данных и снижает вероятность ошибки. Как только мы узнаем, что getValueFromUser работает для одной переменной, она будет работать для любого их количества, сколько нам будет нужно.

В этом суть модульного программирования: возможность написать функцию, протестировать ее, убедиться, что она работает, а затем знать, что мы можем повторно использовать ее столько раз, сколько захотим, и она будет продолжать работать (пока мы не изменим эту функцию – после чего нам придется ее повторно протестировать).

Лучшая практика

Следуйте рекомендациям DRY: «не повторяйся». Если вам нужно сделать что-то более одного раза, подумайте, как изменить свой код, чтобы удалить как можно больше избыточности. Переменные можно использовать для хранения результатов вычислений, которые необходимо использовать более одного раза (чтобы нам не нужно было повторять вычисления). Функции можно использовать для определения последовательности инструкций, которые мы хотим выполнять более одного раза. А циклы (которые мы рассмотрим в следующей главе) можно использовать для выполнения инструкции более одного раза.

Заключение

Возвращаемые значения позволяют функциям возвращать одно значение обратно вызывающей функции.

Функции позволяют минимизировать избыточность наших программ.

Небольшой тест

Вопрос 1

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

Эта программа печатает число 16.

Эта программа не компилируется. Вложенные функции не допускаются.

Эта программа компилируется, но ничего не выводит. Значения, возвращаемые функциями, ни для чего не используются (и, таким образом, отбрасываются).

Эта программа печатает буквы A и B в отдельных строках.

Эта программа не компилируется. Функция printA() возвращает void , которое main() пытается отправить в std::cout . Это приведет к ошибке компиляции.

Эта программа напечатает 5 дважды (в отдельных строках). Оба раза, когда вызывается функция getNumbers() , возвращается значение 5. Когда выполняется инструкция return 5; , функция немедленно завершается, поэтому инструкция return 7; никогда не выполняется.

Эта программа не будет компилироваться, потому что функция имеет недопустимое имя. Мы говорили о правилах именования в уроке «1.7 – Ключевые слова и именование идентификаторов».

1h) Чуть сложнее.

Эта программа будет скомпилирована, но функция не будет вызвана, потому что при вызове функции отсутствуют круглые скобки. То, что на самом деле будет выведено, зависит от компилятора.

Вопрос 2

Что означает «DRY» и почему это полезно?

DRY означает «Don’t Repeat Yourself» (не повторяйся). Это практика, которая включает в себя написание кода таким образом, чтобы минимизировать избыточность. Это делает ваши программы более краткими, менее подверженными ошибкам и более удобными для поддержки.

Источник

  • Remove From My Forums
  • Question

  • Hi All! I have a test function «contains_abc(char* string)» that checks string for containing «a» or «b» or «c» the function syntax is ok, this is the code:

    #define NO_A_NO_B_NO_C 0

    #define CONTAINS_A 1

    #define CONTAINS_B 2

    #define CONTAINS_C 3

    int contains_abc(char* string){
        for(int i=0;i<strlen(string);i++)if(string[i]==»a») return CONTAINS_A;
        for(int i=0;i<strlen(string);i++)if(string[i]==»b») return CONTAINS_B;
        for(int i=0;i<strlen(string);i++)if(string[i]==»c») return CONTAINS_C;

        return NO_A_NO_B_NO_C;
    }

    but after compiling, I get this error C2561 : function must return a value!!?? I don’t know why!?? can you tell me how to fix the problem?thanks.

    • Edited by

      Saturday, August 24, 2013 10:21 AM

Answers

  • Since the code you provided does not produce the error in question, you need to provide either the actual code or a stripped down version that does produce the error. 

    By any chance, is the numeric value missing from any of the #define directives?  Does the error still occur if you change the macros to enums.

    • Proposed as answer by
      Anna Cc
      Tuesday, August 27, 2013 6:55 AM
    • Marked as answer by
      Anna Cc
      Tuesday, August 27, 2013 6:57 AM

  • Now you understand why it is important to cut and paste the code into the message and not retype it.

    • Marked as answer by
      Yuri.B
      Tuesday, September 3, 2013 1:20 PM

  • Remove From My Forums
  • Question

  • Hi All! I have a test function «contains_abc(char* string)» that checks string for containing «a» or «b» or «c» the function syntax is ok, this is the code:

    #define NO_A_NO_B_NO_C 0

    #define CONTAINS_A 1

    #define CONTAINS_B 2

    #define CONTAINS_C 3

    int contains_abc(char* string){
        for(int i=0;i<strlen(string);i++)if(string[i]==»a») return CONTAINS_A;
        for(int i=0;i<strlen(string);i++)if(string[i]==»b») return CONTAINS_B;
        for(int i=0;i<strlen(string);i++)if(string[i]==»c») return CONTAINS_C;

        return NO_A_NO_B_NO_C;
    }

    but after compiling, I get this error C2561 : function must return a value!!?? I don’t know why!?? can you tell me how to fix the problem?thanks.

    • Edited by

      Saturday, August 24, 2013 10:21 AM

Answers

  • Since the code you provided does not produce the error in question, you need to provide either the actual code or a stripped down version that does produce the error. 

    By any chance, is the numeric value missing from any of the #define directives?  Does the error still occur if you change the macros to enums.

    • Proposed as answer by
      Anna Cc
      Tuesday, August 27, 2013 6:55 AM
    • Marked as answer by
      Anna Cc
      Tuesday, August 27, 2013 6:57 AM

  • Now you understand why it is important to cut and paste the code into the message and not retype it.

    • Marked as answer by
      Yuri.B
      Tuesday, September 3, 2013 1:20 PM

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include <iostream>
#include <math.h>
 
using namespace std;
 
void getParam(double &xStart, double &xLast, double &dX, double &E);
void calc(double &xStart, double &xLast, double &dX, double &E);
double getSum(double &x, double &E, int &num);
void echo(double &x, double &res, int &num, int type = 1);
 
void main()
{
    setlocale(LC_ALL, "rus");
    double xStart = 0, xLast = 0, dX = 0, E = 0;
    getParam(xStart, xLast, dX, E);
    calc(xStart, xLast, dX, E);
    return;
}
 
void getParam(double &xStart, double &xLast, double &dX, double &E)
{
    cout << "Введите начальное X: ";
    cin >> xStart;
    if(xStart < 1)
    {
        cout << "Некоректное значение";
        exit;
    }
    cout << "Введите конечное X: ";
    cin >> xLast;
    cout << "Введите приращение X: ";
    cin >> dX;
    cout << "Введите точность вычислений: ";
    cin >> E;
    return;
}
 
void calc(double &xStart, double &xLast, double &dX, double &E)
{
    double localResult = 0;
    int num = 0;
    echo(localResult, localResult, num, 0);
    for(double count = xStart; count <= xLast; count = count + dX)
    {
        num = 0;
        localResult = getSum(count, E, num);
        echo(count, localResult, num);
    }
    return;
}
 
double getSum(double &x, double &E, int &num)
{
    double res = 0, r = 0;
    for(int count = 0;; count++)
    {
        r = 1/((2 * count + 1)*pow(x, (2 * count + 1)));
        if(r >= E)
        {
            num++;
            res = res + r;
            continue;
        }
        return (res*2);
    }
}
 
void echo(double &x, double &res, int &num, int type)
{
    switch(type)
    {
    case 0:
        cout << "--------------------------------" << endl;
        cout << "|   x   |   f(x)  |   count   |" << endl;
        cout << "--------------------------------" << endl;
        break;
    case 1:
        cout << "|  " << x << "   |   " << res << "   |   " << num << "   |" << endl;
        cout << "--------------------------------" << endl;
        break;
    }
    return 0;
    system("pause");
}

Я работал над книгой «Программирование: принципы и практика с использованием C ++», и этот пример был призван показать, как данные могут быть потеряны при преобразовании типов. Но когда я пытался выполнить его, он все время говорил мне «Main»: должен вернуть значение. Я пытался использовать «return 0;» после фигурной скобки для цикла while, но затем он выдавал ошибки вокруг «Unresolved externals».

Я скопировал код из книги в Visual Studio, и все остальное, что я скопировал, сработало, как и ожидалось — кто-нибудь сможет сказать мне, как я могу это исправить, пожалуйста? Я не знаю, почему это происходит с этим конкретным примером или как заставить его перестать запрашивать возвращаемое значение.

Извините, если это глупо, я очень неопытен, и я попытался найти ответ, но предложенные решения, такие как «return 0», не работают :)!

#include "std_lib_facilities.h"
int main()
{
double d = 0;

while (cin >> d)
{

int i = d;
char c = i;
int i2 = c;
cout << "d==" << d
<< " i==" << i
<< " i2==" << i2
<< " char(" << c << ")n";
}
}

-6

Решение

Я пытался использовать «return 0;» после фигурной скобки для цикла while, но затем он выдавал ошибки вокруг «Unresolved externals».

Это отдельная, не связанная с этим проблема, раскрытая путем исправления первой. Добавьте возврат, затем разберитесь с нерешенной внешней ошибкой.

3

Другие решения

Если это вся ваша программа, вы нерешенный внешний скорее всего iostream, Вы должны включить это и использовать правильное пространство имен.

Рассмотрим следующий код:

#include <iostream>

using namespace std;

int main() {
cout << "Hello World!" << endl;
return 0;
}

Еще лучше отказаться от using заявление и использование std::cout так что вам не нужно беспокоиться о столкновении пространства имен. Смотрите этот вопрос Почему «использование пространства имен std;» считается плохой практикой?

#include <iostream>

int main() {
std::cout << "Hello World!" << std::endl;
return 0;
}

-1

Here is my code. Its a simple Craps Game for my programming class but I am getting some build errors that I keep getting stuck on

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
// ConsoleApplication6.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <ctime>
#include <limits>

using namespace std;


int main()
{
    srand(time(0)); 

    int die1, die2 = 0; 
    int roll1, roll2 = 0;
	int pointRoll;
	int anotherRoll;
    char repeat = 'y'; 

    cout << "Welcome. The game is about to begin." <<endl;

    while (repeat == 'y' || repeat == 'Y') 
    {
        cin.ignore(std::numeric_limits<streamsize>::max(), 'n');
                                                                            
        die1 = rand() % 6 + 1;
        die2 = rand() % 6 + 1; 
        roll1 = die1 + die2;

       
        if (roll1 == 7 || roll1 == 11)
			cout << "Your roll was: " << die1 << " + " << die2 << " = " << roll1 <<endl;
        {
           cout << "You win! Would you like to play again? [Y/N]:" << endl;
           cin >> repeat;
        }
        else if (roll1 == 2 || roll1 == 3 || roll1 == 12)
        {
            cout << "Sorry, you lose! Would you like to play again? {Y/N]:" << endl;
            cin >> repeat;
        } 
		else if (roll1 == 4 || roll1 == 5 || roll1 == 6 ||
                   roll1 == 8 || roll1 == 9 || roll1 == 10) {
                                cout <<  die1 << " + " << die2 << " = " << roll1 <<endl;
                        pointRoll = roll1;
		}
		cout << "Are you ready to roll again? Press '1' when ready" << endl;
        cin >> anotherRoll;   
          
        if (anotherRoll == 1){ 
                  
           while (anotherRoll == 1)
           {                                
                         roll1 = die1 + die2; 
                         if (roll1 == pointRoll){
                           cout << "Congradulations, you Win." << endl;
                           return;
                         }
                         else if (roll1 == 7){
                           cout << "Sorry, 7 came up. You crapped out." << endl;
                           return;
                         }
                         else {
                           cout << "You're still in the game. 7 has not yet rolled." << endl;
                           cout << "Are you ready to roll again? Press '1' when ready" << endl;
                         }
                          cin >> anotherRoll; 
                 }
               
           } else {
                    cout << "Invalid entry" << endl;  
           }   
          
    }
    return(0);
}
1>------ Build started: Project: ConsoleApplication6, Configuration: Debug Win32 ------
1>  ConsoleApplication6.cpp
1>c:users\documentsvisual studio 2012projectsconsoleapplication6consoleapplication6consoleapplication6.cpp(14): warning C4244: 'argument' : conversion from 'time_t' to 'unsigned int', possible loss of data
1>c:users\documentsvisual studio 2012projectsconsoleapplication6consoleapplication6consoleapplication6.cpp(39): error C2181: illegal else without matching if
1>c:users\documentsvisual studio 2012projectsconsoleapplication6consoleapplication6consoleapplication6.cpp(59): error C2561: 'main' : function must return a value
1>          c:users\documentsvisual studio 2012projectsconsoleapplication6consoleapplication6consoleapplication6.cpp(12) : see declaration of 'main'
1>c:users\documentsvisual studio 2012projectsconsoleapplication6consoleapplication6consoleapplication6.cpp(63): error C2561: 'main' : function must return a value
1>          c:users\documentsvisual studio 2012projectsconsoleapplication6consoleapplication6consoleapplication6.cpp(12) : see declaration of 'main'
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

1
2
3
4
5
6
if (roll1 == 7 || roll1 == 11)
/* Here*/		cout << "Your roll was: " << die1 << " + " << die2 << " = " << roll1 <<endl;
        {
           cout << "You win! Would you like to play again? [Y/N]:" << endl;
           cin >> repeat;
        }

You have a line of code before the block starts on your if statement, so the block executes AFTER the if whether it evaluated to true or not. Which also means your else if statement directly after that doesn’t match up to your if statement since there was code in between them. Also try just:

at the end of your program

line 33 move the braces on line 35 so it is after the if condition.

lines 59 & 63 return 0; main must return an int

Changed returns to repeats…
Now I am getting


1>------ Build started: Project: ConsoleApplication6, Configuration: Debug Win32 ------
1>  ConsoleApplication6.cpp
1>c:userssarahdocumentsvisual studio 2012projectsconsoleapplication6consoleapplication6consoleapplication6.cpp(14): warning C4244: 'argument' : conversion from 'time_t' to 'unsigned int', possible loss of data
1>c:userssarahdocumentsvisual studio 2012projectsconsoleapplication6consoleapplication6consoleapplication6.cpp(39): error C2181: illegal else without matching if
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

TheIdeasMan wrote:

line 33 move the braces on line 35 so it is after the if condition.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
if (roll1 == 7 || roll1 == 11) { // <----- moved it to here
			cout << "Your roll was: " << die1 << " + " << die2 << " = " << roll1 <<endl;
        {
           cout << "You win! Would you like to play again? [Y/N]:" << endl;
           cin >> repeat;
        }
        else if (roll1 == 2 || roll1 == 3 || roll1 == 12)
        {
            cout << "Sorry, you lose! Would you like to play again? {Y/N]:" << endl;
            cin >> repeat;
        } 
		else if (roll1 == 4 || roll1 == 5 || roll1 == 6 ||
                   roll1 == 8 || roll1 == 9 || roll1 == 10) {
                                cout <<  die1 << " + " << die2 << " = " << roll1 <<endl;
                        pointRoll = roll1;
		}

You should consider having an else clause to catch any bad input or errors.

warning C4244: ‘argument’ : conversion from ‘time_t’ to ‘unsigned int’, possible loss of data

This one is seemingly a little pedantic. Edit: Numbers default to int so, try this:

srand(time(NULL));

Or if you have C++11:

srand(time(nullptr));

Last edited on

Changed returns to repeats…

Don’t know what that means.

Line 34 belongs BEFORE the if.

error C2181: illegal else without matching if

Your if is still messed up.

Last edited on

Wow thank you guys! So far it worked! Now I need to get certain things to display. I believe I can get this on my own though. I feel stupid that it was just those brackets….

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
// ConsoleApplication6.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <ctime>
#include <limits>

using namespace std;


int main()
{
    srand(time(NULL)); 

    int die1, die2 = 0; 
    int roll1, roll2 = 0;
	int pointRoll;
	int anotherRoll;
    char repeat = 'y'; 

    cout << "Welcome. The game is about to begin." <<endl;

    while (repeat == 'y' || repeat == 'Y') 
    {
        cin.ignore(std::numeric_limits<streamsize>::max(), 'n');
                                                                            
        die1 = rand() % 6 + 1;
        die2 = rand() % 6 + 1; 
        roll1 = die1 + die2;

       
        if (roll1 == 7 || roll1 == 11) {
			cout << "Your roll was: " << die1 << " + " << die2 << " = " << roll1 <<endl;
        
           cout << "You win! Would you like to play again? [Y/N]:" << endl;
           cin >> repeat;
        }
        else if (roll1 == 2 || roll1 == 3 || roll1 == 12)
		{
            cout << "Sorry, you lose! Would you like to play again? {Y/N]:" << endl;
            cin >> repeat;
        } 
				else if (roll1 == 4 || roll1 == 5 || roll1 == 6 || roll1 == 8 || roll1 == 9 || roll1 == 10) 
		{
                        cout <<  die1 << " + " << die2 << " = " << roll1 <<endl;
                        pointRoll = roll1;
				}
		cout << "Are you ready to roll again? Press '1' when ready" << endl;
        cin >> anotherRoll;   
          
        if (anotherRoll == 1){ 
                  
           while (anotherRoll == 1)
           {                                
                         roll1 = die1 + die2; 
                         if (roll1 == pointRoll){
                           cout << "Congradulations, you Win." << endl;
                           cin >> repeat;
                         }
                         else if (roll1 == 7){
                           cout << "Sorry, 7 came up. You crapped out." << endl;
                          cin >> repeat;
                         }
                         else {
                           cout << "You're still in the game. 7 has not yet rolled." << endl;
                           cout << "Are you ready to roll again? Press '1' when ready" << endl;
                         }
                          cin >> anotherRoll; 
                 }
               
           } else {
                    cout << "Invalid entry" << endl;  
           }   
          
    }
    return 0;
}

Edited code. Got a new error when I run the program and I lose instantly.
It ask me to press Y then Press 1. Then the error comes

Run-Time Check Failure #3 - The variable 'pointRoll' is being used without being initialized.

Oh and when I run it and I hit one of the pointroll numbers it always wins instead of generating another random #

Last edited on

You can initialise variables to something at declaration — it may give a wrong answer but at least it won’t crash.

Have you used a debugger? IF you have an IDE it should be easy — set up a watchlist of variables, see how the values change as you step through the code 1 line at a time. See where they go wrong & deduce the problem.

You can also put cout statements everywhere in you code to do the same thing. Start with a few to narrow down where the problem is.

Line 44 could just be an else rather than else if, because that would cover the remaining possibilities.

Are lines 52 to 74 necessary? You already have a while loop to play multiple times.

I had removed the lines like you suggested but I still need to have a secondary set of rolls when I roll either a 4 5 6 8 9 or 10 on roll 1.

Also I am using Visual Studio 2012 but I barely know how to use it.

I had removed the lines like you suggested but I still need to have a secondary set of rolls when I roll either a 4 5 6 8 9 or 10 on roll 1.

You can still code that logic into your loop with a RollCount variable.

Also I am using Visual Studio 2012 but I barely know how to use it.

Is that about the debugger? I have never used VS : Is there a debug option on the run Menu? Or use cout like I mentioned above.

If all else fails read the manual.

I use the debugger. The program essentially works. It just doesn’t do what I need it to. Sucks being new at this. I can also step through my program line by line.

Well, then you should be able work out where it goes wrong, by looking at the values of the variables & seeing how the execution moves through the loops & if statements etc.

Assuming your last post of your code is still current, I see I few logic problems.

1) You should put your dice roll logic into a function. Add after line 10:

1
2
3
4
5
6
7
8
9
10
int roll_dice ()
{  int die1, die2; 
    int roll;

    die1 = rand() % 6 + 1;
    die2 = rand() % 6 + 1; 
    roll = die1 + die2;
    cout << "Your roll was: " << die1 << " + " << die2 << " = " << roll <<endl;
    return roll;
}

Delete line16 and 46.
Replace lines 28-30 with:

2) regarding

The variable ‘pointRoll’ is being used without being initialized.

The only place I see that you’ve set pointroll is at line 47. You then check it at line 57. You can reach line 57 without going through line 47 resulting in an uninitialized variable.

3) Line 56. You supposedly roll the dice again, but you haven’t changed the value of die1 or die2. Change line 56 to:

4) Your whole roll again logic from lines 49-74 should be inside your else if at line 44. i.e. move 49-74 to after lne 47. You’re prompting the user for a second roll even if they won or crapped out.

You’re trying to combine additional rolls with playing the game again. This is what is confusing your logic. That should be separate logic.

Thanks AbstractionAnon, I did what you had said. However when II added the diceroll logic above int main() it still tells me that die1 and die2 are undefined. Why is that?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
// ConsoleApplication6.cpp : Defines the entry point for the console application.
//


#include <iostream>
#include <ctime>
#include <limits>

using namespace std;

int roll_dice ()
{   int die1, die2; 
    int roll;

    die1 = rand() % 6 + 1;
    die2 = rand() % 6 + 1; 
    roll = die1 + die2;
    cout << "Your roll was: " << die1 << " + " << die2 << " = " << roll <<endl;
    return roll;
}
int main()
{
    srand(time(NULL)); 

  
    int roll1, roll2 = 0;
	int pointRoll;
	int anotherRoll;
    char repeat = 'y'; 

    cout << "Welcome. The game is about to begin." <<endl;

    while (repeat == 'y' || repeat == 'Y') 
    {
        cin.ignore(std::numeric_limits<streamsize>::max(), 'n');
                                                                            
			roll1 = roll_dice();

       
        if (roll1 == 7 || roll1 == 11) {
			cout << "Your roll was: " << die1 << " + " << die2 << " = " << roll1 <<endl;
        
           cout << "You win! Would you like to play again? [Y/N]:" << endl;
           cin >> repeat;
        }
        else if (roll1 == 2 || roll1 == 3 || roll1 == 12)
		{
            cout << "Sorry, you lose! Would you like to play again? {Y/N]:" << endl;
            cin >> repeat;
        } 
				else if (roll1 == 4 || roll1 == 5 || roll1 == 6 || roll1 == 8 || roll1 == 9 || roll1 == 10) 
		{
 
                        pointRoll = roll1;
								cout << "Are you ready to roll again? Press '1' when ready" << endl;
        cin >> anotherRoll;   
          
        if (anotherRoll == 1){ 
                  
           while (anotherRoll == 1)
           {                                
                         roll1 = roll_dice();
                         if (roll1 == pointRoll){
                           cout << "Congradulations, you Win." << endl;
                           cin >> repeat;
                         }
                         else if (roll1 == 7){
                           cout << "Sorry, 7 came up. You crapped out." << endl;
                          cin >> repeat;
                         }
                         else {
                           cout << "You're still in the game. 7 has not yet rolled." << endl;
                           cout << "Are you ready to roll again? Press '1' when ready" << endl;
                         }
                          cin >> anotherRoll; 
                 }
               
           } else {
                    cout << "Invalid entry" << endl;  
          
    }
    return 0;
}
1>------ Build started: Project: Project2, Configuration: Debug Win32 ------
1>  Source.cpp
1>c:userssarahdocumentsvisual studio 2012projectsproject2project2source.cpp(23): warning C4244: 'argument' : conversion from 'time_t' to 'unsigned int', possible loss of data
1>c:userssarahdocumentsvisual studio 2012projectsproject2project2source.cpp(84): fatal error C1075: end of file found before the left brace '{' at 'c:userssarahdocumentsvisual studio 2012projectsproject2project2source.cpp(35)' was matched
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Last edited on

Ok guys last thing I need help with
I need help with when I go to play again it jumps town to char goAgain. I can’t seem to get this function to work properly. Any tips?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
// #include preprocessor directives
#include <iostream>
#include <cstdlib>            // for using rand() function
#include <ctime>                // for using time() function

// namespace directives
using namespace std ;

void CrapsIntro() ;               // brief description of Craps game
int  CrapsRoll() ;                  // outcome of two six-sided dice rolls      // Function for if chooses passline
char goAgain();         // option if user wants to play again


 int main()
{

           int myRoll;       
           int pointRoll;   // If user hits a "point", it will be stored here
           int anotherRoll;
		   char repeat = 'y'; //when declaring a char with a letter you have to put ' ' around it
           myRoll = CrapsRoll();  // Uses function CrapsRoll() to genereate a random number
          
           if (myRoll == 7 || myRoll == 11){
                   cout << "You win." << endl;
               goAgain();
           }
           else if (myRoll == 2 || myRoll == 3 || myRoll == 12){
                   cout << "Sorry you lose." << endl;
					goAgain();
           }
           else if (myRoll == 4 || myRoll == 5 || myRoll == 6 ||
                   myRoll == 8 || myRoll == 9 || myRoll == 10) {
                                cout << "The number you rolled is a point number." << endl;
                        pointRoll = myRoll;
           }
           cout << "Are you ready to roll again? Press '1' when ready" << endl;
           cin >> anotherRoll;   // Roll again after point is hit
          
           if (anotherRoll == 1){  // If it is true (User entered 1)
                  
             while (anotherRoll == 1)         // If it doesn't hit point or 7,
             {                                // loop is used until it does.
                         myRoll = CrapsRoll();  // dice roll
                         if (myRoll == pointRoll){
                           cout << "Congradulations, you Win." << endl;
                            goAgain();
                         }
                         else if (myRoll == 7){
                           cout << "Sorry, 7 came up. You crapped out." << endl;
                            goAgain();
                         }
                         else {
                           cout << "You're still in the game." << endl;
                           cout << "Are you ready to roll again? Press '1' when ready" << endl;
                         }
                          cin >> anotherRoll;  //go back to the loop to roll again
                 }
               
           } else {
                    cout << "Invalid entry" << endl;  // User did not enter 1.
           }   
          
    }

int CrapsRoll()
    /* The purpose of this function is to create
    a random roll for two die and return to the
    caller. It has another function inside for
    time delay.
    */

        // Pre-Condition: None
        // Post-Condition: Send back to the caller
        // the sum of two die's being randomly rolled
{
        int randomNumber ;                  // a random number
        int dieOne ;                // a six-sided die roll value
        int dieTwo ;                // a six-sided die roll value
       
        // die one
        srand(int(time(0))) ;            // seeding random number generator
        randomNumber = rand() ;   // generate random number
        dieOne = (randomNumber % 6) + 1 ;       // a number between 1 and 6
       
        // die two
        srand(int(time(0))) ;            // seeding random number generator
        randomNumber = rand() ;   // generate random number
        dieTwo = (randomNumber % 6) + 1 ;       // a number between 1 and 6

        cout << "You rolled a " << dieOne + dieTwo << endl ;
       
        return dieOne + dieTwo ;
}

char goAgain()
        /* This function prompts the user if they would
        like to play again. They can either press
        'Y' for yes or 'N' for no.
        */

        // Pre-Condition: None
        // Post-Condition: If 'Y' || 'N' is entered,
        // it sends back to the caller and enters a loop.
{
       cout << "Would you like to play again?" << endl;
           cout << "Enter 'Y' for Yes or 'N' for No." << endl;
           char playAgain;
           cin >> playAgain;

           while (playAgain) {
                   if (playAgain != 'Y' && playAgain != 'N'){
                cout << "Invalid entry. Please select 'Y' or 'N'. (Capitals)" << endl;
           }
           if (playAgain == 'N'){
                   cout << "Thank you for playing. Good Bye" << endl;
               return playAgain;
           }
        else if (playAgain == 'Y'){
                   cout << "Would you like to play again?'" << endl;

                   return playAgain;
        }
         cin >> playAgain;
        }
}

I said to delete what is now line 41. There is no reason to display the dice roll there since you now display what was rolled in roll_dice().

At line 81, you’re missing two }. One to match the if at line 58 and one to match the while at line 33.

I changed it a bit, using the information you provided me. It helped a lot! I changed some of the int names and stuff. You helped me get on the right track. Much appreciated.

I posted my new code above you. I am having a new problem though. I think it might be one of my cin >> or I am not directing the goAgain function properly.

Last edited on

You should have only one call to srand() in your program. It should be at the start of main (after line 20). You don’t want to seed the random number generator each time you roll the dice (lines 81, 86).

Понравилась статья? Поделить с друзьями:
  • Error c2471 cannot update program database
  • Error c2466 невозможно выделить память для массива постоянного нулевого размера
  • Error c2447 отсутствует заголовок функции возможно используется формальный список старого типа
  • Error c2447 missing function header old style formal list
  • Error c2443 конфликт размеров операндов