Меню

Функция типа void возвращающая значение ошибка

rakotwww

0 / 0 / 0

Регистрация: 17.10.2013

Сообщений: 8

1

17.10.2013, 23:46. Показов 5908. Ответов 17

Метки нет (Все метки)


Возникла проблема, при компиляции выдает ошибку «1>c:usersuserdocumentsvisual studio 2012projectslab1lab1lab1.cpp(30): error C2562: main: функция типа «void», возвращающая значение
1> c:usersuserdocumentsvisual studio 2012projectslab1lab1lab1.cpp(23): см. объявление «main»»
Вот код, подскажите, что в нем не так?

C++
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
#include "stdafx.h"
#include "lab1.h"
#include <iostream>
using namespace std;
double NINT(double N1, double N2, double N3, double N4, double N5, double N6){
    double a=N1*2+N2*1+N3*2.5+N4*4+N5*3+N6*0.5;
    return a;}
double Nt(double V){
    double s=(3600*V)/(V+7+0.7*V*V);
    return s;}
double deltaT(double Tc, double Tzl){
    double d=(Tc+Tzl-Tzl)/2;
    return d;}
double alfa(double L, double v, double T){
    double f= L/(L + (v*v)/2+1+1/1.5 +v*T);
    return f;}
double Nmat(double Nint, double L){
    double g=Nint*2*L;
    return g;}
void main(){
    cout<<"vvedite Ng, Nl, Navt, Navt.soch., Ntrol, Nmot, V, L, Tzel, Tkras";
    double Ng, Nl, Navt, Navtsoch, Ntrol, Nmot, V, L, Tzel, Tkras;
    cin>>Ng>>Nl>>Navt>>Navtsoch>>Ntrol>>Nmot>>V>>L>>Tzel>>Tkras;
    double z=NINT(Ng,Nl,Navt,Navtsoch,Ntrol,Nmot)/Nmat(Nt(V),alfa(L,V,deltaT(Tkras,Tzel)));
    cout<<"степень загруженности="<<z<<endl;
    system("pause");
    return 0;
 
}

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



0



kelpo

5 / 5 / 0

Регистрация: 13.10.2013

Сообщений: 34

17.10.2013, 23:48

2

Цитата
Сообщение от rakotwww
Посмотреть сообщение

Возникла проблема, при компиляции выдает ошибку «1>c:usersuserdocumentsvisual studio 2012projectslab1lab1lab1.cpp(30): error C2562: main: функция типа «void», возвращающая значение
1> c:usersuserdocumentsvisual studio 2012projectslab1lab1lab1.cpp(23): см. объявление «main»»
Вот код, подскажите, что в нем не так?

C++
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
#include "stdafx.h"
#include "lab1.h"
#include <iostream>
using namespace std;
double NINT(double N1, double N2, double N3, double N4, double N5, double N6){
    double a=N1*2+N2*1+N3*2.5+N4*4+N5*3+N6*0.5;
    return a;}
double Nt(double V){
    double s=(3600*V)/(V+7+0.7*V*V);
    return s;}
double deltaT(double Tc, double Tzl){
    double d=(Tc+Tzl-Tzl)/2;
    return d;}
double alfa(double L, double v, double T){
    double f= L/(L + (v*v)/2+1+1/1.5 +v*T);
    return f;}
double Nmat(double Nint, double L){
    double g=Nint*2*L;
    return g;}
void main(){
    cout<<"vvedite Ng, Nl, Navt, Navt.soch., Ntrol, Nmot, V, L, Tzel, Tkras";
    double Ng, Nl, Navt, Navtsoch, Ntrol, Nmot, V, L, Tzel, Tkras;
    cin>>Ng>>Nl>>Navt>>Navtsoch>>Ntrol>>Nmot>>V>>L>>Tzel>>Tkras;
    double z=NINT(Ng,Nl,Navt,Navtsoch,Ntrol,Nmot)/Nmat(Nt(V),alfa(L,V,deltaT(Tkras,Tzel)));
    cout<<"степень загруженности="<<z<<endl;
    system("pause");
    return 0;
 
}

перепиши void main() на int main() функция void не может возвращать значения



1



82 / 82 / 44

Регистрация: 14.07.2013

Сообщений: 410

17.10.2013, 23:49

3

насколько я помню функция void не возвращает значения



0



0 / 0 / 0

Регистрация: 17.10.2013

Сообщений: 8

17.10.2013, 23:49

 [ТС]

4

Попробовал, теперь выдает «1>MSVCRTD.lib(crtexew.obj) : error LNK2019: ссылка на неразрешенный внешний символ _WinMain@16 в функции ___tmainCRTStartup
1>C:UsersuserDocumentsVisual Studio 2012Projectslab1Debuglab1.exe : fatal error LNK1120: неразрешенных внешних элементов: 1″



0



5 / 5 / 0

Регистрация: 13.10.2013

Сообщений: 34

17.10.2013, 23:53

5

Цитата
Сообщение от rakotwww
Посмотреть сообщение

Попробовал, теперь выдает «1>MSVCRTD.lib(crtexew.obj) : error LNK2019: ссылка на неразрешенный внешний символ _WinMain@16 в функции ___tmainCRTStartup
1>C:UsersuserDocumentsVisual Studio 2012Projectslab1Debuglab1.exe : fatal error LNK1120: неразрешенных внешних элементов: 1″

На какую строку текста ругается?



0



0 / 0 / 0

Регистрация: 17.10.2013

Сообщений: 8

17.10.2013, 23:55

 [ТС]

6

Цитата
Сообщение от kelpo
Посмотреть сообщение

На какую строку текста ругается?

Вообще никакую строку красным не подчеркивает, просто выдает это и все



0



5 / 5 / 0

Регистрация: 13.10.2013

Сообщений: 34

17.10.2013, 23:56

7

Цитата
Сообщение от rakotwww
Посмотреть сообщение

Вообще никакую строку красным не подчеркивает, просто выдает это и все

дабл клик на ошибку сделай он укажет строку либо пересоздай проект такое тоже бывает



0



82 / 82 / 44

Регистрация: 14.07.2013

Сообщений: 410

17.10.2013, 23:56

8

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



0



5 / 5 / 0

Регистрация: 13.10.2013

Сообщений: 34

17.10.2013, 23:58

9

Цитата
Сообщение от IchimaruGin
Посмотреть сообщение

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

там скорее всего компилятор загнал, пересоздание проекта должно решить проблемму



0



0 / 0 / 0

Регистрация: 17.10.2013

Сообщений: 8

18.10.2013, 00:00

 [ТС]

10

Да, теперь скомпилировалась, но отладка выдает все ту же ошибку



0



82 / 82 / 44

Регистрация: 14.07.2013

Сообщений: 410

18.10.2013, 00:02

11

у меня 1 вопрос вы в визуал студио или в борланде работаете) у меня просто в визуал первые две библиотеки не находит)



0



0 / 0 / 0

Регистрация: 17.10.2013

Сообщений: 8

18.10.2013, 00:04

 [ТС]

12

Visual studio 2012 )



0



82 / 82 / 44

Регистрация: 14.07.2013

Сообщений: 410

18.10.2013, 00:11

13

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

Это сообщение об ошибке сопровождается неустранимой ошибкой LNK1120.

Возможные причины

При обновлении управляемой библиотеки или проекта веб-сервиса из Visual C++ 2003, параметр компилятора /Zl будет добавлен на страницу свойств Командная строка. Это приведет к ошибке LNK2001. Для решения проблемы удалите параметр /Zl на странице свойств Командная строка. Дополнительные сведения см. в разделах /Zl (Опущенное по умолчанию имя библиотеки) и Открытие свойств страниц проекта. Либо добавьте файлы msvcrt.lib и msvcmrt.lib в свойство «Дополнительные зависимости компоновщика».

Запрашиваемое кодом не существует (например, неправильное написание символа, неверный регистр).

Неверный запрос кода (используется смешанная версия библиотек — из разных версий продукта).

От себя добавлю я стёр первые две библиотеки и у меня все успешно компилируется, не знаю в этом ли проблема но можете попробывать….



0



0 / 0 / 0

Регистрация: 17.10.2013

Сообщений: 8

18.10.2013, 00:18

 [ТС]

14

Цитата
Сообщение от IchimaruGin
Посмотреть сообщение

От себя добавлю я стёр первые две библиотеки и у меня все успешно компилируется, не знаю в этом ли проблема но можете попробывать….

Она уже начала компилироваться, там надо было проект новый создать) Теперь отладка не запускается) А компиляция проходит успешно



0



5 / 5 / 0

Регистрация: 13.10.2013

Сообщений: 34

18.10.2013, 00:20

15

Цитата
Сообщение от rakotwww
Посмотреть сообщение

Она уже начала компилироваться, там надо было проект новый создать) Теперь отладка не запускается) А компиляция проходит успешно

ты создавал empty project или нет? если нет то создай через empty project и библиотеку подключи #include <iostream> и все



0



0 / 0 / 0

Регистрация: 17.10.2013

Сообщений: 8

18.10.2013, 00:23

 [ТС]

16

Цитата
Сообщение от kelpo
Посмотреть сообщение

ты создавал empty project или нет? если нет то создай через empty project и библиотеку подключи #include <iostream> и все

через empty project, iostream подключена(в коде же есть)



0



5 / 5 / 0

Регистрация: 13.10.2013

Сообщений: 34

18.10.2013, 00:25

17

Цитата
Сообщение от rakotwww
Посмотреть сообщение

через empty project, iostream подключена(в коде же есть)

значит другие 2 библиотеки удаляй они не нужны



0



0 / 0 / 0

Регистрация: 17.10.2013

Сообщений: 8

18.10.2013, 00:30

 [ТС]

18

Перезапустил VS и все нормально запустилось ) Спасибо



0



Добавлено 9 апреля 2021 в 22:58

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

#include <iostream>
 
int main()
{
	// получаем значение от пользователя
	std::cout << "Enter an integer: ";
	int num{};
	std::cin >> num;
 
	// выводим удвоенное значение
	std::cout << num << " doubled is: " << num * 2 << 'n';
 
	return 0;
}

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

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

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

// Эта программа не работает
#include <iostream>
 
void getValueFromUser()
{
 	std::cout << "Enter an integer: ";
	int input{};
	std::cin >> input;  
}
 
int main()
{
	getValueFromUser(); // Просим пользователя ввести данные
 
	int num{}; // Как нам получить значение из getValueFromUser() 
               // и использовать его для инициализации этой переменной??
 
	std::cout << num << " doubled is: " << num * 2 << 'n';
 
	return 0;
}

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

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

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

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

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

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

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

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

#include <iostream>
 
// int - это тип возвращаемого значения
// Тип возвращаемого значения int означает, что функция вернет вызывающей стороне
// некоторое целочисленное значение (конкретное значение здесь не указано)
int returnFive()
{
    // инструкция возврата указывает конкретное значение, которое будет возвращено
    return 5; // возвращаем конкретное значение 5 обратно вызывающей стороне
}
 
int main()
{
    std::cout << returnFive() << 'n';     // печатает 5
    std::cout << returnFive() + 2 << 'n'; // печатает 7
 
    returnFive(); // хорошо: значение 5 возвращается, но игнорируется, 
                  // поскольку main() ничего с ним не делает
 
    return 0;
}

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

5
7

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

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

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

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

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

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

#include <iostream>
 
int getValueFromUser() // эта функция теперь возвращает целочисленное значение
{
 	std::cout << "Enter an integer: ";
	int input{};
	std::cin >> input;  
 
	return input; // возвращаем значение, введенное пользователем, обратно вызывающей функции
}
 
int main()
{
	int num { getValueFromUser() }; // инициализируем num значением, возвращаемым getValueFromUser()
 
	std::cout << num << " doubled is: " << num * 2 << 'n';
 
	return 0;
}

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

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

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

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

void doPrint() // void is the return type
{
    std::cout << "In doPrint()" << 'n';
    // Эта функция не возвращает значение, поэтому инструкция return не требуется
}

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

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

#include <iostream>
 
// void означает, что функция не возвращает значение вызывающей стороне
void returnNothing()
{
    std::cout << "Hi" << 'n';
    // Эта функция не возвращает значение, поэтому инструкция return не требуется
}
 
int main()
{
    returnNothing(); // хорошо: вызывается функция returnNothing(), значение не возвращается
 
    std::cout << returnNothing(); // ошибка: эта строка не компилируется. 
                                  // Вам нужно будет закомментировать ее, чтобы продолжить.
 
    return 0;
}

При первом вызове функции 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 определены в заголовочном файле <cstdlib>:

#include <cstdlib> // для EXIT_SUCCESS и EXIT_FAILURE
 
int main()
{
    return EXIT_SUCCESS;
}

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

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

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

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

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

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


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

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


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

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

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

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

Например:

// Функция просит пользователя ввести значение
// Возвращаемое значение - это целое число, введенное пользователем с клавиатуры
int getValueFromUser()
{
 	std::cout << "Enter an integer: ";
	int input{};
	std::cin >> input;  
 
	return input; // возвращаем значение, введенное пользователем, обратно вызывающей функции
}

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

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

#include <iostream>
 
int main()
{
	int x{};
	std::cout << "Enter an integer: ";
	std::cin >> x; 
 
	int y{};
	std::cout << "Enter an integer: ";
	std::cin >> y; 
 
	std::cout << x << " + " << y << " = " << x + y << 'n';
 
	return 0;
}

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

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

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

#include <iostream>
 
int getValueFromUser()
{
 	std::cout << "Enter an integer: ";
	int input{};
	std::cin >> input;  
 
	return input;
}
 
int main()
{
    int x{ getValueFromUser() }; // первый вызов getValueFromUser
    int y{ getValueFromUser() }; // второй вызов getValueFromUser
 
    std::cout << x << " + " << y << " = " << x + y << 'n';
 
    return 0;
}

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

Enter an integer: 5
Enter an integer: 7
5 + 7 = 12

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

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

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


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

Заключение

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

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

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

Вопрос 1

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

1а)

#include <iostream>
 
int return7()
{
    return 7;
}
 
int return9()
{
    return 9;
}
 
int main()
{
    std::cout << return7() + return9() << 'n';
 
    return 0;
}

Ответ

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

1b)

#include <iostream>
 
int return7()
{
    return 7;
 
    int return9()
    {
        return 9;
    }
}
 
int main()
{
    std::cout << return7() + return9() << 'n';
 
    return 0;
}

Ответ

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

1c)

#include <iostream>
 
int return7()
{
    return 7;
}
 
int return9()
{
    return 9;
}
 
int main()
{
    return7();
    return9();
 
    return 0;
}

Ответ

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

1d)

#include <iostream>
 
void printA()
{
    std::cout << "An";
}
 
void printB()
{
    std::cout << "Bn";
}
 
int main()
{
    printA();
    printB();
 
    return 0;
}

Ответ

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

1e)

#include <iostream>
 
void printA()
{
    std::cout << "An";
}
 
int main()
{
    std::cout << printA() << 'n';
 
    return 0;
}

Ответ

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

1f)

#include <iostream>
 
int getNumbers()
{
    return 5;
    return 7;
}
 
int main()
{
    std::cout << getNumbers() << 'n';
    std::cout << getNumbers() << 'n';
 
    return 0;
}

Ответ

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

1g)

#include <iostream>
 
int return 5()
{
    return 5;
}
 
int main()
{
    std::cout << return 5() << 'n';
 
    return 0;
}

Ответ

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

#include <iostream>
 
int returnFive()
{
    return 5;
}
 
int main()
{
    std::cout << returnFive << 'n';
 
    return 0;
}

Ответ

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


Вопрос 2

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

Ответ

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

Теги

C++ / CppLearnCppДля начинающихОбучениеПрограммирование

So I have the following function, evidently a void:

static void *CpuStatsTestLoop (void *arg){
    UNUSED (arg);

    rtems_object_set_name(rtems_task_self(), "CPU Usage Thread");

    while (1)
    {
        sleep (CPU_USAGE_REPORT_INTERVAL_SECS);
        rtems_cpu_usage_report();
        rtems_cpu_usage_reset();
    }  
}

and it throws

«cpu_stats.c:98:1: warning: no return statement in function returning non-void [-Wreturn-type]».

I’ve tried adding a blank return and return 0 with no luck.

Any idea about why it’s throwing this error, and how to fix?

Collins Abitekaniza's user avatar

asked Jul 6, 2017 at 17:24

2

This is not a void function, this is a void* (void pointer) function. It must return a value, which must be a pointer to data of any type, or NULL.

In your case, a return is not necessary, because the function never returns: it has a while(1) loop, which runs forever. A better approach is to make it a void function, rather than a void* function, unless it must conform to some predefined function pointer type.

If changing return type is not an option, for example, because you must pass this function as a start_routine parameter of pthread_create you can silence the warning by adding return NULL at the end of the function’s body.

answered Jul 6, 2017 at 17:26

Sergey Kalinichenko's user avatar

4

This function has a return type of void *, i.e. a pointer of any type, not void, so it must return a value.

You could fix this by changing the return type to void. However, it looks like this function is meant to be invoked as a thread, in which case it has to have a signature of void *(*)(void *), so if that’s the case changing the return type is not an option.

Given that this function has a while (1) loop it should never return. Still, the function needs to return something, so put return NULL; at the bottom. That will satisfy the compiler, and it will act as a safety catch in case you later introduce a bug that causes you to break out of the loop.

answered Jul 6, 2017 at 17:35

dbush's user avatar

dbushdbush

199k21 gold badges210 silver badges262 bronze badges

So I have the following function, evidently a void:

static void *CpuStatsTestLoop (void *arg){
    UNUSED (arg);

    rtems_object_set_name(rtems_task_self(), "CPU Usage Thread");

    while (1)
    {
        sleep (CPU_USAGE_REPORT_INTERVAL_SECS);
        rtems_cpu_usage_report();
        rtems_cpu_usage_reset();
    }  
}

and it throws

«cpu_stats.c:98:1: warning: no return statement in function returning non-void [-Wreturn-type]».

I’ve tried adding a blank return and return 0 with no luck.

Any idea about why it’s throwing this error, and how to fix?

Collins Abitekaniza's user avatar

asked Jul 6, 2017 at 17:24

2

This is not a void function, this is a void* (void pointer) function. It must return a value, which must be a pointer to data of any type, or NULL.

In your case, a return is not necessary, because the function never returns: it has a while(1) loop, which runs forever. A better approach is to make it a void function, rather than a void* function, unless it must conform to some predefined function pointer type.

If changing return type is not an option, for example, because you must pass this function as a start_routine parameter of pthread_create you can silence the warning by adding return NULL at the end of the function’s body.

answered Jul 6, 2017 at 17:26

Sergey Kalinichenko's user avatar

4

This function has a return type of void *, i.e. a pointer of any type, not void, so it must return a value.

You could fix this by changing the return type to void. However, it looks like this function is meant to be invoked as a thread, in which case it has to have a signature of void *(*)(void *), so if that’s the case changing the return type is not an option.

Given that this function has a while (1) loop it should never return. Still, the function needs to return something, so put return NULL; at the bottom. That will satisfy the compiler, and it will act as a safety catch in case you later introduce a bug that causes you to break out of the loop.

answered Jul 6, 2017 at 17:35

dbush's user avatar

dbushdbush

199k21 gold badges210 silver badges262 bronze badges

На чтение 1 мин. Просмотров 69 Опубликовано 14.05.2021

Ошибка «недопустимое использование выражения void» возникает в C/C ++, когда мы пытаемся назначить вызов функции void переменной. Это также происходит, когда функция void приводится к другому типу данных.

Код

В следующем коде функция f () имеет тип возврата void . Эта функция передается как аргумент функции g () , которая ожидает в качестве аргумента int . C ++ пытается преобразовать тип возвращаемого значения void функции f () в integer , что вызывает ошибку «недопустимое использование выражения void».

 #include  using namespace std; void f () {cout   

Решение

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

 #include  с использованием пространства имен std; void f () {cout   

0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии

А вот еще интересные материалы:

  • Яшка сломя голову остановился исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного где ошибка
  • Функция ошибок теория вероятности
  • Хамам харвиа е3 03 ошибка