из племени тумба-юбма
![]() |
||||||
1 | ||||||
Откуда у некоторых переменных вместо значения НОЛЬ, присваивается другое значение?15.10.2019, 12:16. Показов 4340. Ответов 50
Метки нет Все метки)
(
Привет, нашел для себя вроде как не плохую и понятную книгу, по обучению Си https://www.kpolyakov.spb.ru/download/devcpp_1.pdf. Сразу в первых примерах на практике, столкнулся с непонятными значениями присвоения переменных.
Кликните здесь для просмотра всего текста
╧ЁштхЄ/Hello a1=0 b1=1 c1=0 a2=0 b2=0 c2=40 x=0 y=0 z=0 n=4203673 Крякозябры кириллицы меня на данном этапе не интересуют. Интересуют сами значения переменных. Откуда у некоторых переменных вместо значения НОЛЬ, присваивается другое значение?
0
|
15.10.2019, 12:16 | |
Ответы с готовыми решениями:
50
Макрос: Eсли Х больше Y, то Z присваивается значение Х, в противном случае Z присваивается значение Y Нужно сделать чтобы при делении на ноль, выводило На ноль делить нельзя, введите другое число Не получается корректно вывести значения некоторых переменных |
Вездепух
![]() ![]() ![]() 12866 / 6731 / 1809
Регистрация: 18.10.2014
Сообщений: 17,035
|
|
17.10.2019, 00:15 | 21 |
"Следует старательно избегать" - это как раз таки не очень категорично. Что-то вроде строгого совета.
Нет никакой разницы между "прототипом" и "реализацией" в этом смысле. Именно такого "неявного int" как раз таки не было. Можно было static a; или volatile a; но не просто a; .Добавлено через 3 минуты Это значит, что такой код не будет содержать constraint violations, т.е. он будет являться корректным с точки зрения компилятора (нет "ошибок компиляции"). Однако это не меняет того факта, что вызов функции с неправильным числом аргументов является неопределенным поведением.
1
|
из племени тумба-юбма
![]() |
|
17.10.2019, 07:04 [ТС] | 22 |
это я учел, спасибо.
Но забавно то, что Dev-C++ компилирует и работает со всеми вариантами, даже с самым дурацким вариантом main(void) . То есть 4 разных варианта синтаксиса, воспринимаются в IDE адекватно. Так же хорошо обстоят дела с командой return 0; , если случайно забыл ее написать, то ничего страшного. Далее по синтаксису, команда cout <<"Уру-ру\n "<<endl; , ее можно писать без конечного оператора - cout <<"Уру-ру\n"; Вот эта вся путаница, на первых этапах знакомства с языком очень напрягает, или просто взрывает мозг. Я могу понять еще разработчиков IDE, они стараются сделать продукт так, чтоб он понимал как оригинальный, так и современный синтаксис правил. Но помимо этого, даже почти во всех учебниках происходит подобная каша, путаница, со старым и новым синтаксисом, с оригинальным Си, и новым Cи++. А если говорить про Visual Studio, так это совсем отдельная каста IDE. Есть оригинальный Си, есть более новый Си++, а еще есть Visual Studio ![]() В общем хочу сказать, что вопросов у меня будет еще довольно много. И такого бардака, пусть даже в самостоятельным изучении, у меня еще не было. Но пока мне это интересно, буду медленно, но стараться осваивать. Всем спасибо за помощь.
0
|
![]() 4044 / 2595 / 431
Регистрация: 09.09.2017
Сообщений: 11,556
|
||||||
17.10.2019, 07:32 | 23 | |||||
Можно. И что? Ну будут в функцию переданы какие-то аргументы, ну будут проигнорированы.
Это-то понятно. Я спрашивал существуют ли такие в реальности. и он тут же перестает быть стандартным. Вы же именно этого и добиваетесь чтобы компилятор подхватил не стандартный заголовок, а ваш, модифицированный. Нет, это значит что количество и тип параметров не определены. Перегрузки функций в Си нет. Учитывая, что ошибкой это не будет, совет слишком строгий. Я вот это имел в виду:
Это просто поддержка старого стандарта. Просто не пользуйтесь устаревшими возможностями, их не просто так запрещают. Вот это правильно. Какой смысл учить С/С++ в среде, которая сама его демонстративно не понимает, приходится подпирать костылями. Это вы еще не сталкивались с разнообразными извращениями.
1
|
из племени тумба-юбма
![]() |
||||||
17.10.2019, 08:21 [ТС] | 24 | |||||
У меня новая непонятнка. В разделе Распространенные ошибки описывается ошибка с циклом for. В данном примере тело цикла не заключено в фигурные скобки и тем не менее, если убрать лишнюю точку с запятой, то цикл работает правильно. Но в моем, случае если закомментировать фигурные скобки, то цикл не работает.
Кликните здесь для просмотра всего текста
Не могу понять почему?
0
|
Вездепух
![]() ![]() ![]() 12866 / 6731 / 1809
Регистрация: 18.10.2014
Сообщений: 17,035
|
|
17.10.2019, 08:47 | 25 |
Компиляторы С имеет право "воспринимать адекватно" все, что угодно, пока они не забывают выдавать диагностические сообщения в ответ на некорректный код. Если у вас компилятор воспринимает
main(void) молча, то это либо баг компилятора, либо это вообще не компилятор стандартного [современного] языка С.А В этом как раз таки нет ничего удивительно и необычного. В функции main действительно не обязательно делать return 0; .
1
|
![]() ![]() ![]() |
|
17.10.2019, 10:21 | 26 |
Грубо говоря, да. Но это не совсем функция с переменным числом аргументов
Это наследие того, что называется "traditional C" (или Си Кернигана-Ритчи). А функции, описанные в таком стиле называют "функции, описанные в стиле Кернигана-Ритчи" (K&R function declaration) Если я правильно понимаю, то великий смысл был такой: C
Скопировано /* Вот так оно объявляется в хидерах. Т.е. известен * только тип результата */ extern int foo(); /* Немного по другому объявляется тело функции * По смыслу это функция с тремя параметрами. Однако если параметр * "a" равен нулю, то поведение функций от других параметров не зависит * и их как бы можно не передавать. Аналогично в случае, если "a" не равно * нулю, а "b" равно нулю, то параметр "c" как бы можно не передавать */ int foo (a, b, c) int a; int b; int c; { if (a == 0) return 0; if (b == 0); return 1; return 2; } int main (void) { /* Вот такие запуски считались корректными */ foo (0); foo (1, 0); foo (1, 2, 3); /* Но в качестве побочного явления можно было написать * вот такие вот некорректные запуски. И компилятор не должен * было ломаться. Всё это проистекло из того, что в общем случае * компилятор видит только прототип из хидера, в котором * нет описания параметров */ foo (1, 2, 3, 4, 5); foo ((double) 1.2, (float)3.4); return 0; } В первых стандартах Си всё это было узаконено. Вероятно, из-за проблем совместимости со старыми кодами. Но есть подозрение, что в современных стандартах оно тоже есть (икать неохота, но gcc поддерживает). Зачем этот балаган держат до сих пор - я не знаю
1
|
![]() 21 / 17 / 4
Регистрация: 31.05.2016
Сообщений: 67
|
|
17.10.2019, 10:47 | 27 |
А как Вы определили, что не работает?
Пройдите пошаговым отладчиком. Сначала миллион раз меняется z, а потом по одному разу остальные переменные.
0
|
из племени тумба-юбма
![]() |
||||||
17.10.2019, 14:04 [ТС] | 28 | |||||
Lady C, нет нигде мануала по Dev-C++, поэтому не умею работать с отладчиком.
Проверял так, после цикла выводится на экран искомая переменная"х"(алгоритм решения взял отсюда). А когда скобки забиты, то результат х=0. Кликните здесь для просмотра всего текста
0
|
![]() 4044 / 2595 / 431
Регистрация: 09.09.2017
Сообщений: 11,556
|
|
17.10.2019, 16:50 | 30 |
Нет. Если указан хоть один параметр (в т.ч. void) функция считается объявленной по современному стандарту, после чего Си честно проверяет соответствие.
0
|
из племени тумба-юбма
![]() |
|
17.10.2019, 19:09 [ТС] | 32 |
Разобрался с отладчиком, удобно и полезно мониторить пошаговый проход. В общем проблему вижу, но не могу понять. При забитых фигурных скобках, цикл крутится только по строкам 9-11 и дальше не идет, почему так?
0
|
Модератор
![]() 8959 / 6725 / 921
Регистрация: 14.02.2011
Сообщений: 23,737
|
|
17.10.2019, 19:20 | 33 |
потому что без фигурных скобок тело цикла это только следующая строка
книжки бы тебе почитать и правила форума тоже, п 5.16
1
|
![]() 4044 / 2595 / 431
Регистрация: 09.09.2017
Сообщений: 11,556
|
|
17.10.2019, 19:24 | 34 |
Я про то, что типичная функция с переменным числом аргументов - printf, там первым параметром идет строка. Ну и у других функций будет примерно то же. Из функции без списка аргументов так просто не вынуть.
0
|
Модератор
![]() 8959 / 6725 / 921
Регистрация: 14.02.2011
Сообщений: 23,737
|
|
17.10.2019, 19:34 | 35 |
где я про это говорил?
перечитай пост 19 Откуда у некоторых переменных вместо значения НОЛЬ, присваивается другое значение? речь шла именно о void foo() а я про что? Evg уже на все ответил ![]() перефразируя старый анекдот: "Можно, но по уставу не положено" ![]()
0
|
Вездепух
![]() ![]() ![]() 12866 / 6731 / 1809
Регистрация: 18.10.2014
Сообщений: 17,035
|
|
17.10.2019, 20:25 | 36 |
Что значит "проигнорированы"? Передача аргументов в функцию может подразумевать набор скрытых действий, которые выполняются безусловно в расчете на то, что аргументы есть. А если их фактически не окажется - все накроется медным тазом. Например, удаление аргументов из стека при выходе из функции.
Добавлено через 3 минуты Так а как же еще? Цикл в C состоит из двух частей: "заголовок" for(...;...;...) , за которым следует "тело" цикла, формально состоящее из одного-единственного statement. Вот у вас и получилось, что строка 11 - это и есть тело цикла.
1
|
![]() 4044 / 2595 / 431
Регистрация: 09.09.2017
Сообщений: 11,556
|
|||||||||||
18.10.2019, 10:48 | 39 | ||||||||||
...выполнять которые задача вызывающей стороны, которая точно знает сколько и чего она передает и, соответственно, может за собой почистить. На этом основана работа функций с переменным числом аргументов.
. Такая функция не сможет узнать сколько и чего ей передано. А если хочется совсем уж странного, можно так:
Или даже так
Хотя нет, второй вариант будет вполне корректным, он не использует пустой список аргументов. Если убрать прототипы, будет совсем не-UB-шно, пичаль
0
|
Вездепух
![]() ![]() ![]() 12866 / 6731 / 1809
Регистрация: 18.10.2014
Сообщений: 17,035
|
|
18.10.2019, 11:16 | 40 |
С чего бы это вдруг? Язык С никогда ничего подобного реализациям не навязывал и ни в коем случае не хочет навязывать. Это было бы заметным ударом по эффективности кода. Требования стандарта языка о соответствии параметров как раз потому так и сформулированы, чтобы ни в коем случае не навязывать "вызывающей стороне" такую "задачу".
С чего бы это вдруг? Во-первых, работу функций с переменным числом аргументов можно организовать множеством разных способов. Во-вторых, при чем здесь вдруг вообще функции с переменным числом аргументов? Добавлено через 6 минут
0
|
18.10.2019, 11:16 | ||||||
Помогаю со студенческими работами здесь
40
Значение присваивается переменной, но не присваивается TexBox Всем элементам массива присваивается ноль
Как вставить, вместо огромного ряда переменных, значения из массива в updateTable? Как сделать чтоб во время работы программы при нажатии определенных клавиш изменялось значение некоторых переменных? Искать еще темы с ответами Или воспользуйтесь поиском по форуму:
|
|
Новые блоги и статьи
![]() |
||||
Циклы for в Python
py-thonny 17.03.2025
Существует множество ситуаций, когда нам нужно выполнить одно и то же действие несколько раз. Цикл for в Python — настоящий рабочий конь для большинства программистов. Если вам нужно пройтись по всем. . .
|
Предсказание ветвлений - путь к высокопроизводительному C++
NullReferenced 17.03.2025
В высокопроизводительном программировании на C++ каждый такт процессора на счету. Когда речь заходит о разработке систем с низкой задержкой — будь то высокочастотная торговля, обработка потоковых. . .
|
Паттерн CQRS в C#
UnmanagedCoder 17.03.2025
Создание сложных корпоративных приложений часто требует нестандартных подходов к архитектуре. Один из таких подходов — паттерн CQRS (Command Query Responsibility Segregation), предлагающий простую,. . .
|
Паттерн Цепочка ответственности в C#
UnmanagedCoder 17.03.2025
Цепочка ответственности — это поведенческий паттерн проектирования, который позволяет передавать запросы последовательно по цепочке потенциальных обработчиков, пока один из них не обработает запрос. . . .
|
Создаем микросервисы с NestJS, TCP и Typescript
run.dev 17.03.2025
NestJS — фреймворк, который значительно упрощает создание серверных приложений на Node. js. Его прелесть в том, что он комбинирует концепции ООП, функционального программирования и предлагает. . .
|
Гексагональная архитектура со Spring Boot
Javaican 17.03.2025
Если вы когда-нибудь сталкивались с ситуацией, когда внесение простых изменений в базу данных или пользовательский интерфейс заставляло вас переписывать весь код, то вы точно оцените элегантность. . .
|
Позиционирование Kafka Consumer и Seek-операции
Javaican 17.03.2025
Что же такое Consumer Seek в Kafka? По сути, это API-метод, который позволяет программно указать, с какой позиции (offset) Consumer должен начать или продолжить чтение данных из партиции. Без этого. . .
|
Python NumPy: Лучшие практики и примеры
py-thonny 17.03.2025
NumPy (Numerical Python) — одна из ключевых библиотек для научных вычислений в Python. Она превращает Python из просто удобного языка общего назначения в среду для проведения сложных математических. . .
|
Java Micronaut в Docker: контейнеризация с Maven и Jib
Javaican 16.03.2025
Когда речь заходит о микросервисной архитектуре на Java, фреймворк Micronaut выделяется среди конкурентов. Он создан с учётом особенностей облачных сред и контейнеров, что делает его идеальным. . .
|
Управление зависимостями в Java: Сравнение Spring, Guice и Dagger 2
Javaican 16.03.2025
Инъекция зависимостей (Dependency Injection, DI) — один из фундаментальных паттернов проектирования, который радикально меняет подход к созданию гибких и тестируемых Java-приложений. Суть этого. . .
|