Easyelectronics.ru

Электроника для всех
Текущее время: 28 фев 2021, 12:49

Часовой пояс: UTC + 5 часов



JLCPCB – Прототипы печатных плат за $2/5шт. два слоя. $5/5шт. четыре слоя
Крупнейший производитель печатных плат и прототипов. Более 600000 клиентов и свыше 10000 заказов в день!
Получите скидку на почтовую отправку при первом заказе в JLCPCB!

Начать новую тему Ответить на тему  [ Сообщений: 307 ]  На страницу Пред.  1, 2, 3, 4, 5, 6, 7 ... 13  След.
Автор Сообщение
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 15 янв 2012, 17:55 
Старожил
Аватара пользователя

Зарегистрирован: 05 ноя 2010, 16:03
Сообщения: 1510
Откуда: Екатеринбург
я всегда явно указываю нужный мне тип переменной)
в данном случае она была объявлена как unsigned char, правил на signed.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 15 янв 2012, 18:06 
Старожил
Аватара пользователя

Зарегистрирован: 01 фев 2010, 18:05
Сообщения: 422
а я раньше думал что размер int равен разрядности проца


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 15 янв 2012, 18:27 
Старожил

Зарегистрирован: 06 фев 2010, 17:22
Сообщения: 1557
Откуда: Иркутск
Это зависит от компилятора. В avr-gcc int - 2 байта.
Например, все тот же stdint.h, обычный glibc в linux:
Код:
typedef int int32_t;

А в stdint.h avr-libc уже так:
Код:
typedef signed int int16_t

Т.е. ни 1, ни 4, а 2 байта.
Это еще один плюс stdint.h - гарантированная размерность типов.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 15 янв 2012, 19:56 
Старожил
Аватара пользователя

Зарегистрирован: 05 ноя 2010, 16:03
Сообщения: 1510
Откуда: Екатеринбург
ещё один вопрос

положим, есть некая функция, возвращающая результат ADC-замера типа uchar.
нужно получить усреднённое из 4х замеров значение.

как я это вижу себе:
- объявляю переменную типа uint,
- суммирую её значение с поступающими замерами,
- в конце концов делю uint на 4.

грабли в том, что функция возвращает uchаr, а я её пытаюсь писать в uint, и компилятор ругается.

как делать правильно?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 15 янв 2012, 20:33 
Старожил
Аватара пользователя

Зарегистрирован: 01 фев 2010, 18:05
Сообщения: 422
используй явное приведение типа
http://ru.wikipedia.org/wiki/Приведение_типа#.D0.92_.D1.8F.D0.B7.D1.8B.D0.BA.D0.B5_C

Код:
uint a;
uchar b;
a = (uint)b;


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 15 янв 2012, 23:03 
Старожил

Зарегистрирован: 28 дек 2010, 03:18
Сообщения: 741
Откуда: Оренбург
bui писал(а):
используй явное приведение типа
В Си, при арифметический операциях над разными целыми типами, все приводятся к int. На сколько я помню.

_________________
arogov.com


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 16 янв 2012, 07:08 
Старожил
Аватара пользователя

Зарегистрирован: 05 ноя 2010, 16:03
Сообщения: 1510
Откуда: Екатеринбург
вот посмотрю сегодня асм-листинг, что там куда приводится


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 16 янв 2012, 11:53 
Старожил
Аватара пользователя

Зарегистрирован: 05 ноя 2010, 16:03
Сообщения: 1510
Откуда: Екатеринбург
да, кстати ещё. как правильно написать сдвиг числа на 2 бита вправо?

по аналогии с ( 1<<i ) --сдвиг единицы влево на i разрядов,
получается, что ( ЧИСЛО >> i ) ? это точно не сдвиг значения i на ЧИСЛО разрядов вправо?

запутался.. и чета википедии на эту тему молчат


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 16 янв 2012, 12:03 
Старожил
Аватара пользователя

Зарегистрирован: 19 фев 2010, 02:32
Сообщения: 565
Откуда: Рязань
что сдвигать>>куда сдвигать
0b01010>>1 = 0b00101

З.Ы.
Не читайте википедию, там занудство и запутанность прогрессирует. Есть хорошие книжки

_________________
После нас - хоть потоп (с) Лойсо


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 16 янв 2012, 12:07 
Старожил
Аватара пользователя

Зарегистрирован: 05 ноя 2010, 16:03
Сообщения: 1510
Откуда: Екатеринбург
точнее, так
ЧТО КУДА КАК_ДАЛЕКО

я правильно понял?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 16 янв 2012, 12:15 
Старожил
Аватара пользователя

Зарегистрирован: 19 фев 2010, 02:32
Сообщения: 565
Откуда: Рязань
Ant писал(а):
точнее, так
ЧТО КУДА КАК_ДАЛЕКО

я правильно понял?

Если под КУДА понимается левый или правый сдвиг - то да, все именно так

_________________
После нас - хоть потоп (с) Лойсо


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 16 янв 2012, 12:41 
Старожил

Зарегистрирован: 03 мар 2010, 14:10
Сообщения: 1514
Откуда: Беларусь, Минск
bui писал(а):
а я раньше думал что размер int равен разрядности проца

В Си int равен разрядности процессора, но не меньше 2х байт. Вот и получаем что для 8ми битников несоответствие. Для avr-gcc есть параметр "-mint8" который сделает int 8ми битным. Это конечно избавит/добавит проблем от integer promotion, но избавит от накладных расходов на неявные преобразования.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 16 янв 2012, 13:09 
Заглядывает иногда

Зарегистрирован: 08 май 2010, 18:00
Сообщения: 172
Ant писал(а):
да, кстати ещё. как правильно написать сдвиг числа на 2 бита вправо?

по аналогии с ( 1<<i ) --сдвиг единицы влево на i разрядов,
получается, что ( ЧИСЛО >> i ) ? это точно не сдвиг значения i на ЧИСЛО разрядов вправо?

запутался.. и чета википедии на эту тему молчат

Сдвиг вправо на N бит аналогичен делению на 2^N
Код:
int a = 4;
int b = 640;
int result = 0;
...
result = a >> 2;    // result = 1;     // аналогично делению на 2^2
result = b >> 4;   // result = 40    // аналогично делению на 2^4


Сдвиг влево по аналогии, только умножение на 2^N
Код:
int a = 4;
int result = 0;
...
result = a << 5;    // result = 128;     // аналогично умножению на 2^5


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 16 янв 2012, 13:25 
Старожил
Аватара пользователя

Зарегистрирован: 05 ноя 2010, 16:03
Сообщения: 1510
Откуда: Екатеринбург
Oxide, you're reading my mind ))


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 19 янв 2012, 10:00 
Старожил
Аватара пользователя

Зарегистрирован: 05 ноя 2010, 16:03
Сообщения: 1510
Откуда: Екатеринбург
а вот ещё один вопрос, тоже об элементарных вещах, я даже где-то видел решение, только найти не могу(

вопрос в каментах к коду
Код:
// есть массив с кодами цифр
char digits [] = {0b00110000, 0b00110001, 0b00110010,
                  0b00110011, 0b00110100, 0b00110101,
                  0b00110110, 0b00110111, 0b00111000, 0b00111001};

unsigned char ADCres;
signed char i;

//массив под конвертированное в текст число
char strNumber [3];
char *ptr;

ptr = strNumber;

//собственно замер опустим, но он был - и он отлажен
// конвертируем замер в строку
itoa(ADCres,ptr,10);

for(i=3; i>=0; i--)
{
   switch(strNumber[i])
   {
      //вот тут затык: понятно, что в strNumber[i] лежит 1 байт
      //но с чем сравнивать, чтобы правильно ответвиться? с ASCII значением символа "0"? или есть какая-то функция, возвращающая ASCII-код вместо символа - чисто для наглядности кода?
      case "0": SymbolPointer = 0; break;
      case "1": SymbolPointer = 1; break;
      case "2": SymbolPointer = 2; break;
      case "3": SymbolPointer = 3; break;
      ...
   }
   SendByte(digits[SymbolPointer]);
}


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 19 янв 2012, 10:09 
Старожил
Аватара пользователя

Зарегистрирован: 26 янв 2010, 21:48
Сообщения: 3965
Откуда: Звенигород
А чем не нравиться SendByte(digits[strNumber[i]-0x30]); вместо всех этих кейсов?

_________________
От Парижа до Находки с водкой лучше, чем без водки!


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 19 янв 2012, 10:12 
Старожил
Аватара пользователя

Зарегистрирован: 05 ноя 2010, 16:03
Сообщения: 1510
Откуда: Екатеринбург
для меня это пока магия.
я на Си писать начал месяц назад, не всё ж сразу.

для начала всё-таки хотелось бы понять, как поступать в моём случае, описанном в вопросе. ну, просто из принципа, чтоб на будущее знать


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 19 янв 2012, 11:46 
Старожил

Зарегистрирован: 03 мар 2010, 14:10
Сообщения: 1514
Откуда: Беларусь, Минск
Ant писал(а):
а вот ещё один вопрос, тоже об элементарных вещах, я даже где-то видел решение, только найти не могу(

вопрос в каментах к коду
Код:
...

Если у вас ADCres - один байт - то у вас может произойти переполнение, так как максимальное значение байта - 255, это 3 символа + терминатор строки. То есть вам надо делать массив на максимальную длину строки + один байт.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 19 янв 2012, 11:49 
Старожил
Аватара пользователя

Зарегистрирован: 05 ноя 2010, 16:03
Сообщения: 1510
Откуда: Екатеринбург
так а запись вида
Код:
char strNumber [3];

разве не означает массива из 4 элементов? - первый-то нулевой

...и кстати,
Код:
чем не нравиться SendByte(digits[strNumber[i]-0x30]); вместо всех этих кейсов?

зачем вообще отнимать 0х30? насколько я вижу, коды цифровых символов HD44780 совпадают с ASCII-кодами цифр.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 19 янв 2012, 12:38 
Старожил

Зарегистрирован: 03 мар 2010, 14:10
Сообщения: 1514
Откуда: Беларусь, Минск
Ant писал(а):
так а запись вида
Код:
char strNumber [3];

разве не означает массива из 4 элементов? - первый-то нулевой

Нет. Это значит ровно столько сколько написано.
Искренне ваш, КО.

P.S. это кстати распространённые среди новичков грабельки. Только у вас наоборот.
Пример работы с массивом
Код:
#define ARR_LEN 100500
SuperType arr[ARR_LEN];
for (int i = ARR_LEN - 1; i >= 0; --i)
{
  DoCoolStuff(arr[i]);
}
// или
for (int i = (sizeof (arr) / sizeof (arr[0])) - 1; i >= 0; --i)
{
  DoMoreCoolStuff(arr[i]);
}

Ключевое тут "-1".


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 19 янв 2012, 12:49 
Старожил
Аватара пользователя

Зарегистрирован: 05 ноя 2010, 16:03
Сообщения: 1510
Откуда: Екатеринбург
Цитата:
распространённые среди новичков грабельки. Только у вас наоборот

да уж, в Си приколов хватает, насколько я вижу.
"стандарты Си VS стандарты всех остальных языков", судя по всему)

за пример спасибо.
кстати, я специально гуглил на тему декремента счетчика. у кого как - кто пишет i--, кто --i
вроде бы, если нет присвоения значения i другой переменной, то разницы не будет?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 19 янв 2012, 12:57 
Старожил

Зарегистрирован: 03 мар 2010, 14:10
Сообщения: 1514
Откуда: Беларусь, Минск
Ant писал(а):
кстати, я специально гуглил на тему декремента счетчика. у кого как - кто пишет i--, кто --i
вроде бы, если нет присвоения значения i другой переменной, то разницы не будет?
Обратите внимание на слова "вроде бы". Они не допустимы. Разница либо есть, либо её нет. Надеется на авось - не лучшее в программировании. Если есть сомнения - проверьте для вашего компилятора, если проект планируете переносить - пишите лучше сразу так, что б не было моментов с неясным толкованием в стандарте.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 19 янв 2012, 13:11 
Старожил

Зарегистрирован: 03 мар 2010, 14:10
Сообщения: 1514
Откуда: Беларусь, Минск
Ant писал(а):
Код:
или есть какая-то функция, возвращающая ASCII-код вместо символа - чисто для наглядности кода?
Нет. Но если надо - можете всегда объявить собственные
Код:
inline int char_to_ascii_code (char c)
{
  return c;
}
...
char c8 = '8';
int n = char_to_ascii_code( c8 ) - char_to_ascii_code( '0' );

Ant писал(а):
...и кстати,
Код:
чем не нравиться SendByte(digits[strNumber[i]-0x30]); вместо всех этих кейсов?

зачем вообще отнимать 0х30? насколько я вижу, коды цифровых символов HD44780 совпадают с ASCII-кодами цифр.

Как известно символу "0" соответствует код 0x30, а цифры в таблице ASCII идут по порядку, отсюда делаем вывод что если у нас есть символ цифры, то отняв номер нуля - мы получим смещение этой цифры относительно нуля в таблице, что нам собственно и надо для замены этого жуткого switch-а. Более наглядно было бы

Код:
SendByte( digits[ strNumber[i] - '0' ] );


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 19 янв 2012, 13:22 
Старожил
Аватара пользователя

Зарегистрирован: 05 ноя 2010, 16:03
Сообщения: 1510
Откуда: Екатеринбург
Цитата:
Обратите внимание на слова "вроде бы". Они не допустимы

я вроде бы задавал вопрос, а не утверждал что-то))

Цитата:
смещение этой цифры относительно нуля в таблице, что нам собственно и надо

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

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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 19 янв 2012, 13:34 
Старожил

Зарегистрирован: 03 мар 2010, 14:10
Сообщения: 1514
Откуда: Беларусь, Минск
Ant писал(а):
Цитата:
смещение этой цифры относительно нуля в таблице, что нам собственно и надо

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


По вашему коду не скажешь что вы хотите сразу выводить ascii коды.
Ant писал(а):
Код:
   switch(strNumber[i])
   {
      case "0": SymbolPointer = 0; break;
      case "1": SymbolPointer = 1; break;
      case "2": SymbolPointer = 2; break;
      case "3": SymbolPointer = 3; break;
      ...
   }
   SendByte(digits[SymbolPointer]);


К тому же упоминания дисплея в исходном сообщении не было.
Вот что получилось без дополнительных магических таблиц:

Код:
unsigned char ADCres;
signed char i;

char strNumber [4];

itoa( ADCres, ptr, 10 );

for( i = 3; i >= 0; --i )
{
   SendByte( strNumber[ i ] );
}
// или даже
const char *p = strNumber;
while ( '\0' != *p )
{
   SendByte( *p );
   ++p;
}


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 307 ]  На страницу Пред.  1, 2, 3, 4, 5, 6, 7 ... 13  След.


Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB