Страница 235 из 386

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

Добавлено: Вт июл 05, 2016 10:02:10
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;
}

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

Добавлено: Вт июл 05, 2016 10:32:05
Hand-Maker
Получилось!!
Пасибки, ловите плюску :wink:

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

Добавлено: Сб июл 09, 2016 20:55:54
____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, но как исправить не пойму
если можно напишите как правильно
спасибо

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

Добавлено: Сб июл 09, 2016 21:45:21
BorisSPB
Скобки не хватает:
#define PULS_CCPR1_DAUN ((_XTAL_FREQ/4UL)/(1000000UL/(PERIOD - PULS)))-1UL

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

Добавлено: Сб июл 09, 2016 21:46:42
____Eugene____
спасибо

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

Добавлено: Пт июл 22, 2016 10:03:12
FreshMan
прошу помощи
есть у меня ф-ция разложения 2 разрадного числа

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

void Scr (int8_t temp)
{
		Screen[0] = temp / 10;
		Screen[1] = temp % 10;
	
}
как ее надо усовершенствовать чтобы она разлаживала 3-х и более разрядные числа ?

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

Добавлено: Пт июл 22, 2016 10:23:50
ARV
FreshMan писал(а):как ее надо усовершенствовать чтобы она разлаживала 3-х и более разрядные числа ?
http://arv.radioliga.com/content/view/106/49/

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

Добавлено: Пт июл 22, 2016 10:31:23
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;
    }
}
Ну, или, если наращивать функционал (отрицательные числа, заполнение нулями/пробелами) - как-то так.

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

Добавлено: Пт июл 22, 2016 10:59:11
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;
}

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

Добавлено: Пт июл 22, 2016 11:30:48
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;
    }
}
, то разница будет ещё больше

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

Добавлено: Пт июл 22, 2016 12:15:13
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:

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

Добавлено: Пт июл 22, 2016 12:21:38
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] должен быть самой правой цифрой.

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

Добавлено: Пт июл 22, 2016 12:27:18
FreshMan
WiseLord писал(а):А вообще, нумеровать разряды слева направо - неправильно.
почему ?

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

Добавлено: Пт июл 22, 2016 12:42:25
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;
    }
}

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

Добавлено: Пт июл 22, 2016 12:57:56
FreshMan
ух ты, спасибо ! :)

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

Добавлено: Пт июл 22, 2016 14:15:28
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".

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

Добавлено: Пт июл 22, 2016 14:21:16
ARV
WiseLord писал(а):Ну так поехали дальше
вообще говоря, я давал ссылку, где все это рассказано в деталях...

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

Добавлено: Пт июл 22, 2016 14:56:46
WiseLord
А я и не говорю, что там что-то не так. В своё время тоже практически к тому же коду пришёл:
https://github.com/WiseLord/ampcontrol/ ... lay.c#L549.

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

Добавлено: Сб июл 23, 2016 20:04:43
FreshMan
для определения разрядности числа использую ф-цию

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

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

как определить разрядность отрицательного числа ?

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

Добавлено: Сб июл 23, 2016 20:14:14
WiseLord
Очевидно,

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

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