из племени тумба-юбма
![]() |
||||||
1 | ||||||
Откуда у некоторых переменных вместо значения НОЛЬ, присваивается другое значение?15.10.2019, 12:16. Показов 4331. Ответов 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 Нужно сделать чтобы при делении на ноль, выводило На ноль делить нельзя, введите другое число Не получается корректно вывести значения некоторых переменных |
![]() 4043 / 2590 / 431
Регистрация: 09.09.2017
Сообщений: 11,553
|
|
18.10.2019, 11:44 | 41 |
С чего бы это вдруг?
Недостатки очистки вызываемой стороной очевидны, но вот недостатков очистки вызывающей с ходу придумать не могу. При том, что принцип работы всех функций один и тот же, естественно. Просто не примере функций с переменным числом аргументов и вызовом функции по указателю (где число и тип аргументов точно так же неизвестны) это механизм виден наиболее наглядно. Добавлено через 9 минут Покопался немного по стандарту: . И там же куча примеров конкретно с int main(), можете пробежаться поиском. Я насчитал 2 примера без списка параметров, 2 с пустым списком (void) и 1 с полным списком (argc, argv)
0
|
Вездепух
![]() ![]() ![]() 12862 / 6727 / 1809
Регистрация: 18.10.2014
Сообщений: 17,029
|
||||||
18.10.2019, 12:05 | 42 | |||||
Именно с того, что преимущества очистки параметров вызывающей стороной настолько существенны, что практически все аппаратные платформы заточены под такой вариант уже на аппаратном уровне. Стандарт языка С, разумеется, сформулирован в расчете на то, что реализации будут следовать именно этой эффективной технике кодогенерации.
Естественно нет. "Принцип работы" функций с переменным числом параметров не имеет ничего общего с "принципом работы" обычных функций. Это вы можете увидеть и в любом ABI, и это отражено и в том факте, что стандарт языка С во все века и времена требовал предварительного объявления функций с переменным числом параметров. Именно потому, что такие функции не имеют ничего общего с обычными функциями. Функции с переменным числом параметров всегда были сущностями особого рода. Имеется в виду, что с точки зрения тела этой функции, параметров у нее нет. С точки зрения объявления, которое вводится таким определением, параметры неспецифицированы. То есть никакой разницы в этом отношении между объявлением и определением нет. Вопрос этот давно разъяснен и закрыт: http://www.open-std.org/jtc1/s... dr_317.htm Можно даже делать рекурсивный "неправильный" вызов такой функции из самой себя
Выражение "список аргументов не указан в прототипе" - оксиморон. Если в прототипе "не указан список аргументов", то это никак не прототип. Это совсем не важно, что там в примерах. Мой совет избегать объявлений с () основан только на том, что все K&R объявления официально являются obsolescent, то есть находятся в процессе удаления из языка. Это удаление еще не произошло.
0
|
![]() 4043 / 2590 / 431
Регистрация: 09.09.2017
Сообщений: 11,553
|
|
18.10.2019, 12:35 | 43 |
Вы повторили то, что я сказал: после вызова функции стек и все прочее чистит вызывающая сторона. Следовательно, если вызываемая сознательно его не портит, никакого UB и не будет. А смысл тогда был спорить?
Так отличия-то найдете? Вполне определено - бесконечная рекурсия. А что? И вряд ли произойдет, поскольку единственное, что оно делает - ломает совместимость и снижает читаемость. Ни на безопасности, ни на предсказуемости кода это не скажется. В лучшем случае снимут кальку с С++, где отсутствие списка аргументов эквивалентно пустому списку. Тем более что на практике оно почти всегда так и используется.
0
|
Вездепух
![]() ![]() ![]() 12862 / 6727 / 1809
Регистрация: 18.10.2014
Сообщений: 17,029
|
|
18.10.2019, 12:55 | 44 |
Нет, просто опечатался. Речь, разумеется, шла об очистке стека вызываемой строной. И спора тут н какого нет - я лишь констатирую факты.
Нет, конечно, первый же вызов с неправильным количеством параметров - неопределенное поведение. Ни до какой "бесконечной рекурсии" дело тут дойти не успевает. Вы уж определитесь, о чем вы говорите: о собственных "мечтах" по поводу языка С или о реальном стандартном языке. А то у вас то чтение стандарта начинается, то собственные выдумки, то снова чтение стандарта, то снова выдумки... Объявление без прототипа, что же еще? По-моему эти азы языка тут уже много раз тут разжевывались, в том числе мной. Ломает совместимость, но астрономическиски повышает читаемость и существенно повышает безопасность. А "произойдет" или "не произойдет" - это дело десятое. Просто не нужно пользоваться deprecated свойствами языка. А уж когда их удалят и удалят ли вообще - не важно.
0
|
![]() 4043 / 2590 / 431
Регистрация: 09.09.2017
Сообщений: 11,553
|
||||||
18.10.2019, 15:06 | 45 | |||||
Которая, очевидно, сложнее и опаснее, чем вызывающей. Что дальше?
А если подумать? А если проверить? Кликните здесь для просмотра всего текста
Если подумать: вызывающая сторона заполняет стек и регистры, после чего вызывает функцию, дожидается ее завершения и сбрасывает указатель стека обратно. Вызываемая функция считает, что параметров ей не положено, поэтому содержимое стека просто игнорирует. Поведение вполне безопасное и предсказуемое. Если проверить:
А, то есть вот это int func(); уже объявление без прототипа. И давно?Ломает совместимость, немного снижает читаемость и не влияет на безопасность. А, собственно, ради чего? . Вы приводите какие-то свои домыслы, не подкрепленные ничем: ни логикой, ни цитатами из стандарта, ни конкретными примерами, демонстрирующими то или иное поведение. Может, все-таки перейдете к конструктиву?
0
|
Вездепух
![]() ![]() ![]() 12862 / 6727 / 1809
Регистрация: 18.10.2014
Сообщений: 17,029
|
|
18.10.2019, 17:38 | 46 |
Не понял. О чем именно "подумать"? Не пошутили ли авторы стандарта?
"Проверить" что? "Проверить" неопределенное поведение??? ![]() Простите, это троллинг или вам просто нечего делать? Пожалуйста, не оскорбляйте присутствующих таким апофеозом вопиющего идиотизма, как попытки "проверять" неопределенное поведение практическими примерами или "подкреплять" тут что-то ими. Да, конечно! Это именно объявление без прототипа. И не "уже", а всегда было! Похоже, начинать нужно именно с таких азов. А давно ли... С того момента, как в языке появились прототипы, то есть С первого стандарта языка С. 1989 год. Вы действительно не знаете, когда появился стандарт языка? Все мои утверждения подтверждены стандартом языка и ссылки на него я здесь не раз уже приводил. Если вам не понятен какой раздел стандарта описывает какой из вышеупомянутых моментов - спрашивайте
0
|
![]() 4043 / 2590 / 431
Регистрация: 09.09.2017
Сообщений: 11,553
|
|
19.10.2019, 09:12 | 47 |
Проверить ваше утверждение:
И стандарт, и логика, и эксперимент подтверждает, что вызов такой функции прекрасно работает. Я хотел сказать, что код совершенно исправен, но бесконечная рекурсия не позволяет. То есть у функции будет два определения. А зачем тогда, по-вашему, вводили термин "прототип"? Ссылок на стандарт в этой теме не было вообще. Самое близкое - моя цитата и предложение поискать в стандарте примеры, но без номера называть прямо "ссылкой" слишком сильно. Если у вас есть ссылки, где указывается, что передача в функцию, объявленной без аргументов, чего-то другого, будет UB, приводите, конечно.
0
|
Вездепух
![]() ![]() ![]() 12862 / 6727 / 1809
Регистрация: 18.10.2014
Сообщений: 17,029
|
|
19.10.2019, 10:38 | 48 |
Ну зачем же впрямую врать? Стандарт открытым текстом говорит, что вызов функции с неправильным числом аргументов вызывает неопределенное поведение. Логика такого решения ясна и прозрачна.
От того, что вы будете непрерывно дылдонить обратное, ситуация не поменяется. И ваши попытки "опровергнуть" неопределенные поведение каким-то частными примерами вызывают лишь улыбку. Чего? Какие еще "два определения"? В языке С исторически поддерживается два взаимоисключающих синтаксиса объявления (и определения) функции: K&R синтаксис (объявление без прототипа) и новый синтаксис, похожий на С++-объявления (объявление с прототипом). Объявления второго типа - с прототипом - часто называют просто прототипами. Объявления первого типа "прототипами" никто никогда не называет. Кроме безграмотных "пионэров", разумеется. А ввели объявления с прототипом (и термин "прототип") в стандартизованный язык потому, что K&R-синтаксис не накладывает на вызов функции никаких компиляторных проверок и ограничений, и посему опасен, крив и неудобен. А вот базовая корректность вызовов функций с прототипами прекрасно проверяется компилятором, а также позволяет компилятору проводить неявные преобразования типов аргументов к типам параметров. Вызов функции, объявленной без прототипа, с неправильным числом и типами аргументов является неопределенным поведением: http://port70.net/~nsz/c/c11/n1570.html#6.5.2.2p6 "If the expression that denotes the called function has a type that does not include a prototype, the integer promotions are performed on each argument, and arguments that have type float are promoted to double. These are called the default argument promotions. If the number of arguments does not equal the number of parameters, the behavior is undefined.[...]If the function is defined with a type that does not include a prototype, and the types of the arguments after promotion are not compatible with those of the parameters after promotion, the behavior is undefined, except for the following cases: - one promoted type is a signed integer type, the other promoted type is the corresponding unsigned integer type, and the value is representable in both types; - both types are pointers to qualified or unqualified versions of a character type or void." Вызов функции, объявленной с прототипом, с неправильным числом и типами аргументов является некорректным кодом (т.е. "ошибкой компиляции"): http://port70.net/~nsz/c/c11/n1570.html#6.5.2.2p2 "If the expression that denotes the called function has a type that includes a prototype, the number of arguments shall agree with the number of parameters. Each argument shall have a type such that its value may be assigned to an object with the unqualified version of the type of its corresponding parameter." У людей, слабо знакомых с тонкостями языка, может вызывать с затруднение определение принадлежности объявлений с () - это старое K&R-объявление или прототип? Для человека, знакомого со стандартом языка, ответ очевиден - это K&R-объявление, что и иллюстрируется нашими экспериментами. Я вам выше также дал ссылку на разъяснения комитета по стандартизации по поводу определений функции с () , где ясно сказано, что несмотря на фразу "у функции нет параметров" в тексте стандарта, такое определение все равно не вводит прототипа, то есть не фиксирует количество и типы параметров.
0
|
![]() 4043 / 2590 / 431
Регистрация: 09.09.2017
Сообщений: 11,553
|
|
19.10.2019, 20:54 | 49 |
Не вызов, а использование. А в примере использования как раз нет.
Да вот и чувствую, что хоть об стенку стучись. Механизм возможного UB вы так и не привели, реальных примеров тоже. Единственное что было - намек в стандарте, который не полностью соответствует задаче.
0
|
Вездепух
![]() ![]() ![]() 12862 / 6727 / 1809
Регистрация: 18.10.2014
Сообщений: 17,029
|
|
20.10.2019, 00:57 | 50 |
Чего???
![]() На весь этот поток чуши я уже отвечал выше. Я думаю, народ, что тут бесполезно дальше тратить время.
0
|
![]() 4043 / 2590 / 431
Регистрация: 09.09.2017
Сообщений: 11,553
|
|
20.10.2019, 14:04 | 51 |
да тут на вашу чушь все равно кроме меня никто времени не тратит, не переживайте.
0
|
20.10.2019, 14:04 | ||||||
Помогаю со студенческими работами здесь
51
Значение присваивается переменной, но не присваивается TexBox Всем элементам массива присваивается ноль
Как вставить, вместо огромного ряда переменных, значения из массива в updateTable? Как сделать чтоб во время работы программы при нажатии определенных клавиш изменялось значение некоторых переменных? Искать еще темы с ответами Или воспользуйтесь поиском по форуму:
|
|
Новые блоги и статьи
![]() |
||||
Простая нейросеть на КуМир: Создание и обучение
EggHead 16.03.2025
Искусственные нейронные сети — удивительная технология, позволяющая компьютерам имитировать работу человеческого мозга. Если вы хотя бы немного интересуетесь современными технологиями, то наверняка. . .
|
Исполнитель Кузнечик в КуМир: Решение задач
EggHead 16.03.2025
Среди множества исполнителей в системе КуМир особое место занимает Кузнечик — простой, но невероятно полезный виртуальный персонаж, который перемещается по числовой прямой, выполняя ваши команды. На. . .
|
Исполнитель Водолей в КуМир: Решение задач
EggHead 16.03.2025
Разработка алгоритмического мышления — одна из ключевых задач для начинающих программистов, и система КуМир предлагает отличный способ погрузиться в этот процесс. Среди множества исполнителей в этой. . .
|
Исполнитель Чертежник в КуМир: Решение задач
EggHead 16.03.2025
Представьте, что вы можете рисовать на бесконечной координатной плоскости, перемещая точку, которая оставляет след. По вашей команде она может поднять перо и двигаться, не оставляя следа, или. . .
|
Исполнитель Робот в КуМир: Решение задач
EggHead 16.03.2025
КуМир (Комплект Учебных МИРов) — это учебная среда программирования, разработанная специально для обучения базовым концепциям алгоритмизации. Её главная фишка — использование русскоязычного. . .
|
Исполнитель Черепаха в КуМир: Решение задач
EggHead 16.03.2025
Представьте, что вы впервые учитесь программировать, а перед вами стоит задача заставить маленькую виртуальную черепашку рисовать на экране. Звучит забавно? Эта идея зародилась ещё в 1967 году, когда. . .
|
Конвейеры данных с Apache Kafka
Javaican 16.03.2025
В мире, где данные стали новой нефтью, Apache Kafka зарекомендовал себя как мощный инструмент для построения надежных и масштабируемых конвейеров данных. Созданный изначально командой LinkedIn в 2011. . .
|
Deno против Node.js: Будущее JavaScript рантайма
run.dev 16.03.2025
За последнее десятилетие Node. js стал абсолютным лидером среди JavaScript-рантаймов и фактическим стандартом для серверной разработки на JavaScript. Но в 2018 году тот же разработчик, который создал. . .
|
SwiftUI или UIKit - что выбрать для нового приложения iOS?
mobDevWorks 16.03.2025
Когда Apple представила SwiftUI на WWDC 2019, многим показалось, что дни UIKit сочтены. Новый декларативный фреймворк предлагал радикально иной подход к разработке интерфейсов. Вместо кропотливого. . .
|
Docker: Руководство для начинающих по созданию первого приложения
Mr. Docker 16.03.2025
Docker — это платформа, которая упаковывает ваше приложение и все его зависимости в стандартизированные блоки, называемые контейнерами. Эти контейнеры изолированы друг от друга и от основной системы,. . .
|