Вопросы по С/С++ (СИ)

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Аватара пользователя
menzoda
Вымогатель припоя
Сообщения: 535
Зарегистрирован: Вт авг 28, 2012 22:21:33

Re: Вопросы по С/С++ (СИ)

Сообщение menzoda »

Код: Выделить всё

// foo.h

typedef struct
{
    uint32_t a:2;
    uint32_t b:21;
    uint32_t c:4;
} flags_t;

extern flags_t flags;


Код: Выделить всё

// foo.c

flags_t flags;


Код: Выделить всё

// main.c

#include "foo.h"

int main(void)
{
    flags.a = 1;
    flags.b = 3;
    flags.c = 2;
}
Аватара пользователя
Hand-Maker
Поставщик валерьянки для Кота
Сообщения: 2142
Зарегистрирован: Чт дек 12, 2013 11:18:14
Откуда: Украина, Черновцы

Re: Вопросы по С/С++ (СИ)

Сообщение Hand-Maker »

Получилось!!
Пасибки, ловите плюску :wink:
____Eugene____
Открыл глаза
Сообщения: 47
Зарегистрирован: Вт авг 31, 2010 18:26:35

Re: Вопросы по С/С++ (СИ)

Сообщение ____Eugene____ »

Здравствуйте
подскажите пожалуйста чего оно ругается

1 #define _XTAL_FREQ 20000000UL
2 #define PERIOD 5000UL //us
3 #define PULS 1000UL //us
4 #define PULS_CCPR1_UP ((_XTAL_FREQ/4UL)/(1000000UL/PULS))-1UL
5 #define PULS_CCPR1_DAUN ((_XTAL_FREQ/4UL)/(1000000UL/(PERIOD - PULS))-1UL
..................
6 CCPR1+=PULS_CCPR1_DAUN;

я подозреваю что непонятно вот это :(PERIOD - PULS) в строке 5, но как исправить не пойму
если можно напишите как правильно
спасибо
BorisSPB
Встал на лапы
Сообщения: 145
Зарегистрирован: Ср фев 01, 2012 10:55:53

Re: Вопросы по С/С++ (СИ)

Сообщение BorisSPB »

Скобки не хватает:
#define PULS_CCPR1_DAUN ((_XTAL_FREQ/4UL)/(1000000UL/(PERIOD - PULS)))-1UL
____Eugene____
Открыл глаза
Сообщения: 47
Зарегистрирован: Вт авг 31, 2010 18:26:35

Re: Вопросы по С/С++ (СИ)

Сообщение ____Eugene____ »

спасибо
Аватара пользователя
FreshMan
Друг Кота
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Re: Вопросы по С/С++ (СИ)

Сообщение FreshMan »

прошу помощи
есть у меня ф-ция разложения 2 разрадного числа

Код: Выделить всё

void Scr (int8_t temp)
{
      Screen[0] = temp / 10;
      Screen[1] = temp % 10;
   
}

как ее надо усовершенствовать чтобы она разлаживала 3-х и более разрядные числа ?
Tell Me The Truth
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение ARV »

FreshMan писал(а):как ее надо усовершенствовать чтобы она разлаживала 3-х и более разрядные числа ?
http://arv.radioliga.com/content/view/106/49/
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение WiseLord »

ARV писал(а):разлаживала 3-х и более разрядные числа
Не разлаживала, а раскладывала.

Как-то так, например:

Код: Выделить всё

void Scr (int8_t temp, uint8_t N)
{
    char i;

    for (i = N; i >= 0; i++) {
        Screen[i] = temp % 10;
        temp /= 10;
    }
}


Ну, или, если наращивать функционал (отрицательные числа, заполнение нулями/пробелами) - как-то так.
Аватара пользователя
FreshMan
Друг Кота
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Re: Вопросы по С/С++ (СИ)

Сообщение FreshMan »

попробовал для начала сам, без подсказок

Код: Выделить всё

void Scr(int16_t temp)
{
      Screen[1] =  temp / 10000;
      Screen[2] = (temp % 10000)/1000;
      Screen[3] = (temp % 1000)/100;
      Screen[4] = (temp % 100)/10;
      Screen[5] =  temp % 10;
}
Tell Me The Truth
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение WiseLord »

Зачем все эти 10000? Это продуцирует дико неоптимальный код

Одной десятки хватит за глаза. /10 и %10 - больше не нужно. Если циклов не понимаете, можно и без них:

Код: Выделить всё

void Scr(int16_t temp)
{
    Screen[5] = temp % 10;
    temp /= 10;
    Screen[4] = temp % 10;
    temp /= 10;
    Screen[3] = temp % 10;
    temp /= 10;
    Screen[2] = temp % 10;
    temp /= 10;
    Screen[1] = temp;
}

Сравните размер прошивки со своим вариантом и сами увидите.

А если то же самое ещё и в цикл завернуть:

Код: Выделить всё

void Scr(int16_t temp)
{
    int8_t i;

    for (i = 5; i >= 0; i--) {
        Screen[i] = temp % 10;
        temp /= 10;
    }
}
, то разница будет ещё больше
Аватара пользователя
FreshMan
Друг Кота
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Re: Вопросы по С/С++ (СИ)

Сообщение FreshMan »

мой вариант
AVR Memory Usage
----------
Device: atmega328p

Program: 2534 bytes (7.7% Full)
(.text + .data + .bootloader)

Data: 53 bytes (2.6% Full)
(.data + .bss + .noinit)


Finished building: sizedummy



ваш вариант_1

Код: Выделить всё

void Scr(int16_t temp)
{
    Screen[5] = temp % 10;
    temp /= 10;
    Screen[4] = temp % 10;
    temp /= 10;
    Screen[3] = temp % 10;
    temp /= 10;
    Screen[2] = temp % 10;
    temp /= 10;
    Screen[1] = temp;
}

AVR Memory Usage
----------
Device: atmega328p

Program: 2546 bytes (7.8% Full)
(.text + .data + .bootloader)

Data: 53 bytes (2.6% Full)
(.data + .bss + .noinit)


Finished building: sizedummy



ваш вариант_2

Код: Выделить всё

void Scr(int16_t temp)
{
    int8_t i;

    for (i = 5; i >= 0; i--) {
        Screen[i] = temp % 10;
        temp /= 10;
    }
}

AVR Memory Usage
----------
Device: atmega328p

Program: 2488 bytes (7.6% Full)
(.text + .data + .bootloader)

Data: 53 bytes (2.6% Full)
(.data + .bss + .noinit)


Finished building: sizedummy

ваши варианты безусловно краше но компилятор почемуто это не оценил :dont_know:
Tell Me The Truth
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение WiseLord »

2534 байтов против 2488 - это, вообще-то, целых 46 байтов экономии. Причём последний код легко сделать расширяемым на нужное число цифр:

Код: Выделить всё

void Scr(int16_t temp, uint8_t n)
{
    int8_t i;

    for (i = n; i >= 0; i--) {
        Screen[i] = temp % 10;
        temp /= 10;
    }
}

А вообще, нумеровать разряды слева направо - неправильно. Screen[0] должен быть самой правой цифрой.
Аватара пользователя
FreshMan
Друг Кота
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Re: Вопросы по С/С++ (СИ)

Сообщение FreshMan »

WiseLord писал(а):А вообще, нумеровать разряды слева направо - неправильно.

почему ?
Tell Me The Truth
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение WiseLord »

Это просто логично.

Например:

429 = 4*10² + 2 * 10¹ + 9 * 10
94783 = 9*10 + 4*10³ + 7*10² + 8*10¹ + 3*10

Логично, что индексом 0 должны быть именно единицы числа.

А если нумеровать слева направо, то вообще непонятно, что эти индексы массива тогда значат.

Заполняя число справа налево, легко остановиться и перестать выводить ненужные нули:

Код: Выделить всё

void Scr(int16_t temp, uint8_t n)
{
    int8_t i;
 
    for (i = n; i >= 0; i--)
      Screen[i] = ' ';

    for (i = n; i >= 0; i--) {
        Screen[i] = temp % 10 + '0';
        temp /= 10;
        if (!temp)
          break;
    }
}
Аватара пользователя
FreshMan
Друг Кота
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Re: Вопросы по С/С++ (СИ)

Сообщение FreshMan »

ух ты, спасибо ! :)
Tell Me The Truth
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение WiseLord »

Ну так поехали дальше. Почему бы и ' ' не передавать в качестве параметра:

Код: Выделить всё

void Scr(int16_t temp, uint8_t n, char fill)
{
    int8_t i;
 
    for (i = n; i >= 0; i--)
      Screen[i] = fill;

    for (i = n; i >= 0; i--) {
        Screen[i] = temp % 10 + '0';
        temp /= 10;
        if (!temp)
          break;
    }
}
Тогда Scr(5, 2, '0') выведет "05", а Scr(5, 2, ' ') просто " 5".
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение ARV »

WiseLord писал(а):Ну так поехали дальше
вообще говоря, я давал ссылку, где все это рассказано в деталях...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение WiseLord »

А я и не говорю, что там что-то не так. В своё время тоже практически к тому же коду пришёл:
https://github.com/WiseLord/ampcontrol/ ... lay.c#L549.
Аватара пользователя
FreshMan
Друг Кота
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Re: Вопросы по С/С++ (СИ)

Сообщение FreshMan »

для определения разрядности числа использую ф-цию

Код: Выделить всё

void RazradnostChisla (int16_t x)
{
   uint8_t i;
   while (x>0)
   {
      x/=10;
      ++i;
   }
   raz_chisla=i;
}


как определить разрядность отрицательного числа ?
Tell Me The Truth
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение WiseLord »

Очевидно,

Код: Выделить всё

if (x < 0)
  x = -x;
и поехали...
Кстати, у меня нет уверенности, что i в самом начале равно нулю. Там может быть любой мусор, в принципе.
Ответить

Вернуться в «Разные вопросы по МК»