Аватар для AHTOH33
0 / 0 / 0
Регистрация: 12.05.2017
Сообщений: 20

Можно ли вручную вызвать метод main()

11.07.2017, 18:08. Показов 3947. Ответов 23
Метки main (Все метки)

Студворк — интернет-сервис помощи студентам
у меня в книге по C++ написано, что метод main() является зарезервированным системой и что его невозможно вызвать вручнуюкак обычную функцию, но тем не менее код представленный ниже прекрасно компилируется и корректно работает, стандарт использую C++11, этот же стандарт является последним на момент написания книги, код представлен ниже
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
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#include <iostream>
#include <ctime>
#include <cstdlib>
 
bool checknum(int, char *);
bool checkwin(char *, char *);
int checkrightpos(char *, char *, int);
int checkrightdig(char *, char *, int);
bool checkinvalidinput(char *, int);
void setpause(float i);
 
bool first = true;
 
int main()
{
    std::srand(time(NULL));
    const int numsize = 5;
    char *number, *answer, *testanswer;
    int *rightdig, *rightpos, *attempts;
    number = new char[numsize];
    attempts = new int;
    for(int i = 0; i < numsize; i++){
        do
            number[i] = std::rand() % 10 + 48;
        while(i != 0 && checknum(i, number));
    }
    number[numsize - 1] = '\0';
    if(first)
        std::cout << "Hello, welcome to the Logic Game!\n";
    first = false;
    std::cout << "Number has generated.\nYou have 10 attempts, start!" << std::endl;
    std::cout << "Enter the number: ";
    rightdig = new int;
    rightpos = new int;
    answer = new char[numsize];
    testanswer = new char[100];
    *attempts = 10;
    while(std::cin.getline(testanswer,100)){
        for(int i = 0; i < numsize - 1; i++)
            answer[i] = testanswer[i];
        answer[numsize - 1] = '\0';
        if(checkinvalidinput(answer, numsize - 1)){
            std::cout << "Invalid input! Enter again: ";
            continue;
        }
        if(*attempts == 1)
            break;
        else
            (*attempts)--;
        if(checkwin(answer, number))
            break;
        *rightdig = checkrightdig(answer, number, numsize - 1);
        *rightpos = checkrightpos(answer, number, numsize - 1);
        std::cout << "You number is\t   " << answer <<". ";
        std::cout << *rightdig << " right numbers," << *rightpos << " in right position.\n";
        std::cout << *attempts << " attempts.\n";
        std::cout << "Enter again: ";
        continue;
    }
    if(*attempts == 1)
        std::cout << "You Lose! Right number is " << number << "!\n";
    else
        std::cout << "You won for " << 10 - *attempts << " attempts!" << std::endl;
    std::cout << "Wanna play again?(y/n): ";
    delete [] number;
    delete rightdig;
    delete rightpos;
    delete [] answer;
    delete [] testanswer;
    delete attempts;
    answer = new char[100];
    while(std::cin.getline(answer,100) && answer[0] != 'n' && answer[0] != 'N'){
        switch (answer[0]){
        case 'Y':
        case 'y':
            main();. dspdfn
        default:
            std::cout << "Incorrect input, enter again: ";
            continue;
        }
    }
    delete [] answer;
    std::cout << "Okay, bye!";
    setpause(1);
    return 0;
}
 
bool checknum(int j, char *num){
    bool outbool = false;
    for(int i = j - 1; i >= 0; i--){
        if(num[i] == num[j]){
            outbool = true;
            break;
        }
    }
    return outbool;
}
 
bool checkwin(char *answer, char *right){
    bool outbool = true;
    for(int i = 0; answer[i] != '\0'; i++){
        if(answer[i] != right[i])
            outbool = false;
    }
    return outbool;
}
 
bool checkinvalidinput(char *input, int inputsize){
    bool outbool = false;
    if(sizeof(input) > inputsize)
        outbool = true;
    else
        for(int i = 0; i < inputsize; i++)
            if(!isdigit(input[i])){
                outbool = true;
                break;
            }
    for(int i = 1; i < inputsize; i++){
        for(int j = i - 1; j < i; j++)
            if(input[j] == input[i]){
                outbool = true;
                break;
            }
        if(outbool)
            break;
    }
    return outbool;
}
 
int checkrightdig(char *answer, char *right, int numsize){
    int rightnums = 0;
    for(int i = numsize - 1; i >= 0; i--)
        for(int j = numsize - 1; j >= 0; j--)
            if(answer[i] == right[j]){
                rightnums++;
                break;
            }
    return rightnums;
}
 
int checkrightpos(char *answer, char *right, int numsize){
    int rightnums = 0;
    for(int i = 0; i < numsize; i++)
        if(answer[i] == right[i])
            rightnums++;
    return rightnums;
}
 
void setpause(float i){
clock_t sec = i * CLOCKS_PER_SEC;
clock_t secpause = clock();
while(clock() - secpause < sec);
}
Добавлено через 9 минут
Там строчка где main() символов нет после точки с запятой, это я слуцайно набил и не заметил уже на сайте.
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
11.07.2017, 18:08
Ответы с готовыми решениями:

Можно ли из программы вызвать метод main()?
Прошу помощи! Ситуация следующая: я разрабатываю на Java под Android, в C не очень разбираюсь. Есть библиотека FFmpeg для работы с видео....

Как вызвать метод info в метод Main и с какими параметрами?
я новичок в C#, так что не судите строго.. Я не думаю что это кому-то покажется сложным, но у меня вызывает дикий ступор(( using...

Метод main и как им вызвать другой метод
Доброго всем времени суток. У меня возникла проблема. Вобщем дело такое. У меня есть тестовый класс Test, в котором существует 4 метода:...

23
с++
1282 / 523 / 225
Регистрация: 15.07.2015
Сообщений: 2,562
11.07.2017, 18:14
прочитай что такое рекурсия
http://cppstudio.com/post/418/
0
Любитель чаепитий
 Аватар для GbaLog-
3745 / 1801 / 566
Регистрация: 24.08.2014
Сообщений: 6,020
Записей в блоге: 1
11.07.2017, 18:15
Лучший ответ Сообщение было отмечено AHTOH33 как решение

Решение

какой у вас компилятор?
если gcc(на винде mingw) или clang, то можете добавить ключик -pedantic-errors и тогда у вас не будет этот код компилироваться.
для vc++, я уверен, тоже есть какой-нибудь ключ, который более жестоко привязывается к стандарту, но точно не знаю.
а вообще да, по стандарту main() ручками вызывать нельзя.
1
11.07.2017, 18:19

Не по теме:

Цитата Сообщение от AHTOH33 Посмотреть сообщение
Можно ли вручную вызвать метод main()
Цитата Сообщение от AHTOH33 Посмотреть сообщение
код представленный ниже прекрасно компилируется и корректно работает
Сам задал вопрос, сам ответил :)

0
Любитель чаепитий
 Аватар для GbaLog-
3745 / 1801 / 566
Регистрация: 24.08.2014
Сообщений: 6,020
Записей в блоге: 1
11.07.2017, 18:21
pav1uxa, это не ответ, компилируется != соответствует стандарту.
в gcc, к примеру, есть vla, которые по-умолчанию включены, но это не по стандарту.
ещё в gcc по-умолчанию можно вызывать main, но это противоречит стандарту.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12919 / 6787 / 1817
Регистрация: 18.10.2014
Сообщений: 17,169
11.07.2017, 18:32
main можно вызывать рекурсивно в С, но нельзя в С++. Даже если ваш С++ компилятор не жалуется на такой вызов, поведение все равно не определено.
1
с++
1282 / 523 / 225
Регистрация: 15.07.2015
Сообщений: 2,562
11.07.2017, 18:47
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
main можно вызывать рекурсивно в С, но нельзя в С++
я знаю что это ошибка но я думал что это работает как и в си спасибо буду знать, только не понимаю а зачем это использовать в своей программе?
0
11.07.2017, 19:23

Не по теме:

Antikl, на днях в тестике по Си на сайте pskills получил подобный вопрос. Там было что-то типа:

C++
1
2
3
4
5
void main()
{
     printf("----");
     main();
}
И вопрос сколько раз напечатается строка. и ответы 1) 1 2) бесконность 3) Ошибка компиляции 4) Ошибка рантайма. Я тупанул и тыкнул ошибку компиляции и оказался неправ(

0
Заклинатель змей
 Аватар для DobroAlex
705 / 560 / 219
Регистрация: 30.04.2016
Сообщений: 2,605
11.07.2017, 19:40
Antikl, можно придумать такую странную реализацию
C
1
2
3
4
5
6
7
8
9
10
int main(){
someShit();
if (getchar() == 'y'){ // вывод запроса на повторное исполнение, нормальный человек напишет возвращение наверх по коду
    main ();
}
else {
   return 0;
}
return 0;
}
0
11.07.2017, 19:55

Не по теме:

Цитата Сообщение от Alex0x0000058 Посмотреть сообщение
можно придумать такую странную реализацию
В коде, который привел автор, так и есть.

0
с++
1282 / 523 / 225
Регистрация: 15.07.2015
Сообщений: 2,562
11.07.2017, 20:02
Цитата Сообщение от Alex0x0000058 Посмотреть сообщение
// вывод запроса на повторное исполнение, нормальный человек напишет возвращение наверх по коду
я не скажу что у меня большой опыт в программировании ну можно в огромном коде так написать main (); и без Отладчик думаю будет вызывать ошибку которую тяжело отыскать это будет не приемлемо, хотя повторю что у меня маленький опыт который я набрал с книжек, ну за пример спасибо.
Цитата Сообщение от _SayHelli Посмотреть сообщение
2) бесконность
подумал за этот ответ
0
 Аватар для _SayHello
874 / 535 / 175
Регистрация: 30.07.2015
Сообщений: 1,739
11.07.2017, 20:07
Antikl,
Цитата Сообщение от Antikl Посмотреть сообщение
подумал за этот ответ
таки он и есть)
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12919 / 6787 / 1817
Регистрация: 18.10.2014
Сообщений: 17,169
11.07.2017, 20:28
Цитата Сообщение от _SayHelli Посмотреть сообщение
И вопрос сколько раз напечатается строка. и ответы 1) 1 2) бесконность 3) Ошибка компиляции 4) Ошибка рантайма. Я тупанул и тыкнул ошибку компиляции и оказался неправ(
Во-первых, ошибку компиляции тот можно получить только за void main().

Во-вторых, вызов printf без предварительного объявления - это неопределенное поведение в "классическом" С и ошибка начиная С99.

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

Поэтому никакого "правильного ответа" тут быть не может. Точнее правильный ответ: после void main() говорить уже не о чем. Программа ошибочна.
2
11.07.2017, 21:59

Не по теме:

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
если компилятор действительно сделал рекурсию
А иначе может быть? Бывают компиляторы которые сделают из этого нерекурсию?

0
11.07.2017, 22:03

Не по теме:

Цитата Сообщение от pav1uxa Посмотреть сообщение
А иначе может быть?
https://ru.wikipedia.org/wiki/... 0%B8%D1%8F
Оптимизация хвостовой рекурсии путём преобразования её в плоскую итерацию реализована во многих оптимизирующих компиляторах. В некоторых функциональных языках программирования спецификация гарантирует обязательную оптимизацию хвостовой рекурсии.

0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12919 / 6787 / 1817
Регистрация: 18.10.2014
Сообщений: 17,169
11.07.2017, 22:07
Цитата Сообщение от pav1uxa Посмотреть сообщение
А иначе может быть? Бывают компиляторы которые сделают из этого нерекурсию?
Разумеется. Практически любой уважающий себя современный компилятор превратит хвостовую рекурсию в цикл. Т.е. данный пример кода будет фактически странслирован как

C
1
2
3
4
5
6
void main()
{
start:
     printf("----");
     goto start;
}
0
 Аватар для AHTOH33
0 / 0 / 0
Регистрация: 12.05.2017
Сообщений: 20
12.07.2017, 06:33  [ТС]
Цитата Сообщение от Antikl Посмотреть сообщение
прочитай что такое рекурсия
С рекурсией я прекрасно знаком, иначе не стал бы использовать нечто подобное
Цитата Сообщение от GbaLog- Посмотреть сообщение
какой у вас компилятор?
Цитата Сообщение от GbaLog- Посмотреть сообщение
ещё в gcc по-умолчанию можно вызывать main, но это противоречит стандарту.
У меня как раз gcc, видимо в этом и суть
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
main можно вызывать рекурсивно в С, но нельзя в С++. Даже если ваш С++ компилятор не жалуется на такой вызов, поведение все равно не определено.
Я писал что программа работает абсолютно корректно, тестировалась несколько раз и все разы был необходимый и ожидаемый результат, никакой непредсказуемости не было. А сделано это было для перезапуска программы если кто вдруг ещё не понял, ответ GbaLog- считаю наиболее правильным и вопрос объявляю решённым.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12919 / 6787 / 1817
Регистрация: 18.10.2014
Сообщений: 17,169
12.07.2017, 06:49
Цитата Сообщение от AHTOH33 Посмотреть сообщение
У меня как раз gcc, видимо в этом и суть
Вот именно GCC как раз таки и откажется рекурсивно вызвать main.

C++
1
2
3
4
int main(void) 
{
    main();
}
Code
1
2
3
4
5
6
g++ -std=c++14 -pedantic-errors main.cpp
 
main.cpp: In function 'int main()':
main.cpp:3:10: error: ISO C++ forbids taking address of function '::main' [-Wpedantic]
     main();
          ^
Цитата Сообщение от AHTOH33 Посмотреть сообщение
программа работает абсолютно корректно, тестировалась несколько раз и все разы был необходимый и ожидаемый результат, никакой непредсказуемости не было.
Во-первых, неопределенное поведение не диагностируется "тестированием несколько раз". Даже хотя бы потому, что никакого смысла в этом нет. А аргументы из разряда "уменявсеработает!!11" могут вызвать лишь снисходительную улыбку. Сегодня "работает", завтра перестанет.

Во-вторых, я даже подошел к вопросу чересчур мягко: попытка вызова main в С++ программе является не неопределенным поведением, а прямым нарушением правил языка, т.е. немедленной ошибкой. Компилятор обязан ткнуть вас носом в ошибку при помощи диагностического сообщения (см. выше). Если ваш компилятор этого не сделал, это либо означает то, что вы работаете не с С++, либо то, что ваш компилятор - малость глюковат.
0
с++
1282 / 523 / 225
Регистрация: 15.07.2015
Сообщений: 2,562
12.07.2017, 07:09
Цитата Сообщение от AHTOH33 Посмотреть сообщение
А сделано это было для перезапуска программы
так зачем это использовать если есть цыклы и есть goto, хотя цыклы лучше, к примеру do{}while(); зачем в программе делать что то не предсказуемое?
Хотя если вопрос решен и вас это устраивает ваше дело.
0
 Аватар для AHTOH33
0 / 0 / 0
Регистрация: 12.05.2017
Сообщений: 20
12.07.2017, 08:03  [ТС]
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Во-первых, неопределенное поведение не диагностируется "тестированием несколько раз". Даже хотя бы потому, что никакого смысла в этом нет. А аргументы из разряда "уменявсеработает!!11" могут вызвать лишь снисходительную улыбку. Сегодня "работает", завтра перестанет.
Возможно и так, спорить не стану, просто подчеркну то, что за несколько пробных запусков у меня неожиданностей не было
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
это либо означает то, что вы работаете не с С++
Забавно, Я не настолько глуп, чтобы не знать с каким языком работаю
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
либо то, что ваш компилятор - малость глюковат.
Он не глюковат, просто как писалось выше у него отсутствуюет ключ -pedantic-errors, который у вас присутствует, поэтому у меня ошибки и нет, но после установки данного флага всё должным образом перестаёт компилироватся и выдаёт ту же ошибку
Цитата Сообщение от Antikl Посмотреть сообщение
так зачем это использовать если есть цыклы и есть goto, хотя цыклы лучше, к примеру do{}while(); зачем в программе делать что то не предсказуемое?
Хотя если вопрос решен и вас это устраивает ваше дело.
goto использовать не люблю, так как затрудняет читабельность кода, да и вроде как я ещё не знал о нём на момент написания, касательно цикла можно было, но как то в голову не пришло. А программа эта писалась просто так, для самого факта написания и закрепления изученного, править я её не собираюсь, просто стало интересно по каким причинам мне удалось без ошибки компиляции вызвать main()
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
12.07.2017, 08:03
Помогаю со студенческими работами здесь

Как вызвать метод в main()
Помогите решить задачу, а то из универа выгонят. Не могу понять, как в мэйне вызвать эту функцию class Program { ...

Reflection. Как вызвать конструктор и метод в Main'e?
Доброго всем времени суток. уже 2ой пытаюсь разобраться с reflection, перечитал кучу инфы, пересмотрел много примеров, но так и не смог...

Как вызвать в Main метод из другого класса?
Задачка на среднее арифметическое. Создал класс &quot;Array&quot;, в котором происходит заполнение массива числами, затем числа из массива и...

Из main вызвать две задачи, при этом сразу вернуть управление в main
Не нашел нигде.. гугл не помог (отчасти только). Вопрос такой, есть консольное приложение. Код main static void Main() { ...

Можно ли переименовать метод Main?
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

Новые блоги и статьи
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
Расскажи мне о Мире, бродяга
kumehtar 12.11.2025
— Расскажи мне о Мире, бродяга, Ты же видел моря и метели. Как сменялись короны и стяги, Как эпохи стрелою летели. - Этот мир — это крылья и горы, Снег и пламя, любовь и тревоги, И бескрайние. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru