Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 09.07.2017, 14:40   #1
tutejshy
Форумчанин
 
Регистрация: 13.05.2017
Сообщений: 100
По умолчанию scanf и %d

При компиляции программ с флагом -Wall часто вижу предупреждение что scanf требуется тип int. Дело в том, что когда я програvмирую и требуются небольшие значения я присваиваю тип char (все-таки что 1 байт, а что 4). Проги все так же работают, но возможны ли ошибки? Может я делаю неправильно?

Код:
int main (void)
{
    unsigned char a;
    scanf ("%d", &a);
    return;
}
PS Читал, что ф-ция scanf не особенно безопасна и может приводить к ошибкам - какую ф-цию ввода можно использовать вместо нее?

Последний раз редактировалось tutejshy; 10.07.2017 в 09:22.
tutejshy вне форума Ответить с цитированием
Старый 09.07.2017, 17:07   #2
Cuprum5
Форумчанин
 
Регистрация: 09.05.2017
Сообщений: 735
По умолчанию

Ваш код вызывает исключение вот в этой строке:
Цитата:
Сообщение от tutejshy Посмотреть сообщение
scanf ("%d", a);
- потому что нужно писать вот так:
Код:
scanf("%d", &a);
Напишу программу на C++ и Asm для AVR. Черчение: sergeisky@yahoo.com.

Последний раз редактировалось Cuprum5; 09.07.2017 в 17:11.
Cuprum5 вне форума Ответить с цитированием
Старый 09.07.2017, 17:51   #3
Black Fregat
Программист
Участник клуба
 
Аватар для Black Fregat
 
Регистрация: 23.06.2009
Сообщений: 1,772
По умолчанию

Когда написано
Код:
scanf("%d", &a);
- по адресу переменной будет перетёрто столько байт, сколько нужно для int. Если Вы решили "сэкономить", возможно, запортите память следом.

Компилятор именно об этом предупреждает, но запретить не может - вдруг Вы действительно хотите выстрелить себе в ногу?

Экономия на байтах в данном случае совершенно не оправдана - во-первых, с большой вероятностью её съест выравнивание, во-вторых, работа с байтами, как ни странно, потребует бОльших ресурсов процессора
Black Fregat вне форума Ответить с цитированием
Старый 10.07.2017, 09:32   #4
tutejshy
Форумчанин
 
Регистрация: 13.05.2017
Сообщений: 100
По умолчанию

Цитата:
- потому что нужно писать вот так:
Код:


scanf("%d", &a);

Просто описка - не заметил, проблема не в этом.

Цитата:
по адресу переменной будет перетёрто столько байт, сколько нужно для int.
блин, а ведь верно! Проверил на массиве и реально затирает 4 байта - не знал, спасибо.
tutejshy вне форума Ответить с цитированием
Старый 10.07.2017, 14:01   #5
Black Fregat
Программист
Участник клуба
 
Аватар для Black Fregat
 
Регистрация: 23.06.2009
Сообщений: 1,772
По умолчанию

Если всё ещё непонятно: scanf от переменной получает только адрес.
А вот что с этим адресом делать, она определяет по спецификатору формата.
Написано %d - значит, scanf будет считать, что на стеке в этом месте адрес int
Black Fregat вне форума Ответить с цитированием
Старый 10.07.2017, 14:16   #6
tutejshy
Форумчанин
 
Регистрация: 13.05.2017
Сообщений: 100
По умолчанию

Понял, немного подправил прогу - теперь scanf в ф-ции, которая возвращает char. Теперь ввожу как int (в пределах char, конечно), а в main возвращает уже char.
tutejshy вне форума Ответить с цитированием
Старый 13.07.2017, 11:43   #7
digitalis
Старожил
 
Аватар для digitalis
 
Регистрация: 04.02.2011
Сообщений: 4,546
По умолчанию

Цитата:
Сообщение от Black Fregat Посмотреть сообщение
по адресу переменной будет перетёрто столько байт, сколько нужно для int.
Мерзкая, на мой взгляд, Сишная ловушка для юзеров. В давние времена, когда я еще писал на Си, долго не мог понять, почему при
Код:
scanf("%f", &a);
затирается следующая за а переменная. Потом обратил внимание, что формата "%f" вообще нет, а есть только "%lf", и даже если мне нужно 0,5, он выдает на выход double-вую 0,500000000.... И никаких варнингов
digitalis вне форума Ответить с цитированием
Старый 13.07.2017, 11:55   #8
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Цитата:
Сообщение от digitalis Посмотреть сообщение
формата "%f" вообще нет
Есть.
Цитата:
Сообщение от digitalis Посмотреть сообщение
И никаких варнингов
Вообще-то должны быть варнинги в нормальном компиляторе.
http://rextester.com/YFOC70684
http://rextester.com/MEL58695
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Старый 13.07.2017, 16:29   #9
digitalis
Старожил
 
Аватар для digitalis
 
Регистрация: 04.02.2011
Сообщений: 4,546
По умолчанию

Много времени прошло, еще из прошлого тысячелетия. Попытался воспроизвести -получилось с точностью до наоборот. Почему - Hz . Компилятор - древний Борланд. Возможно, дело в настройках.
Код:
#include <stdio.h>
#include <io.h>
#include <string.h>
float a,b ; 
void main (void)
{
 b = 5.0 ;
 scanf ("%lf",&a) ; printf ("%f %f\n",a,b) ;
 b = 5.0 ;
 scanf ("%f",&a) ; printf ("%f %f\n",a,b) ;
}
И никаких варнингов ! Приведенные Вами примеры иллюстрируют лишь warning при несовпадении форматной строки с типом переменной, но не с длиной.
А до каких высот докатился интеллект теперешних Сишных компиляторов - я не в курсе, давно от Си отошел, так что понятие "нормальный компилятор" - для меня - увы ...
Изображения
Тип файла: jpg scanf.JPG (5.2 Кб, 45 просмотров)

Последний раз редактировалось digitalis; 13.07.2017 в 16:33.
digitalis вне форума Ответить с цитированием
Старый 13.07.2017, 16:45   #10
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

как это не с длиной? char это число, меньше int.

Ну и с float тоже есть.
http://rextester.com/UDBFM11845
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
%ls и %lc в printf и scanf Krasiosoft Помощь студентам 2 08.07.2015 22:30
scanf cocacola Общие вопросы C/C++ 1 10.07.2014 05:09
scanf zla9_kolu4ka Общие вопросы C/C++ 2 26.03.2014 21:48
scanf intmain Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 25 20.02.2013 17:53
аналог scanf() turtles Общие вопросы по Java, Java SE, Kotlin 1 09.04.2011 10:33