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

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

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

Сообщение Gudd-Head »

WiseLord писал(а):Если бы было так

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

static up;
up = 0;
, то обнулялась бы, а так

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

static up = 0;
- не будет, как уже выше сказали.
Всё чудесатей и чудесатей :)
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Реклама
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

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

Сообщение WiseLord »

По поводу "@" - думаю, это какой-то атрибут, возможно специфический для какой-то архитектуры (а не вообще для языка C). Что-то наподобие "_at_" здесь.
Реклама
Аватара пользователя
menzoda
Вымогатель припоя
Сообщения: 535
Зарегистрирован: Вт авг 28, 2012 22:21:33

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

Сообщение menzoda »

Gudd-Head писал(а):Всё чудесатей и чудесатей
Так, вы тут Gudd-Head давайте не путайте, обнуляется не обнуляется.

Статическая переменная объявленная в функции сохраняет свое значение между вызовами функции. Если при объявлении она инициализируется, то это происходит один раз при первом вызове функции. В остальном - это обычная переменная.

Хотя я сейчас посмотрел стандарт C99 и там написано, что static инициализируется перед запуском программы, а не при первом вызове функции. Перепутал с C#.
Последний раз редактировалось menzoda Чт окт 09, 2014 13:15:55, всего редактировалось 1 раз.
Аватара пользователя
просто КОТ
Друг Кота
Сообщения: 12364
Зарегистрирован: Пт дек 17, 2010 15:07:50
Откуда: Крымский Федеральный Округ
Контактная информация:

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

Сообщение просто КОТ »

Друзья, есть маленький вопрос и большая проблема. Я программист всего месяца полтора как. Если не меньше... Надо мне отправить строку следующего вида: L=xx /n. Где хх это содержимое переменной light.
Спойлер

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

#include "stdio.h"
char res[8];


/********Тут**по***идее**код*************/

if(send) {  
			sprintf (res, "%s %d", "L=", light);  
        	Out_Str(res); mUart_Putch(0x0D);
			send=0;
}
Функция Out_Str отправляет строку и работает железно. Но вот сама строка не формируется никак. Код без этих шести строк занимал 37% памяти и работал чётко. Дописав их к основному коду получил 114% памяти и собственно кучу глюков. Вопрос -- что не так, и как быть?
Спойлер

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

#define 	F_CPU 8000000UL

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdlib.h>
#include "mUart.h"
#include "stdio.h"

char light = 1;
char b = 1;
char res[8];
/****************************************************************/


volatile unsigned char   tx_fl=0;
volatile unsigned char   TSK_CLR=0;
volatile unsigned char   ID=83;

volatile unsigned char rx;
volatile unsigned char rx_buf[10];
volatile unsigned char rx_cnt=0;
volatile unsigned char rx_fl=0;
volatile unsigned char rx_size;
volatile unsigned char err=0;
volatile unsigned char send=0;


/****************************************************************/
/*                       Ñäåëàòü çàìåð ôîòîäàò÷èêà                         */
/****************************************************************/

ISR (TIM1_OVF_vect)  {
if(ADCH > 0x63 && b < 6) b++;
if(ADCH < 0x63 && b > 0) b--;
	light = 16*b + 1;
	ADCSRA|= (1<<ADSC);
	send=1;
}
/****************************************************************/
/*                       Ïðèíÿò áàéò                            */
/****************************************************************/
void CallBack_RX(char ch){

rx=ch;

if(err)   return;

rx_buf[rx_cnt]=ch;

if(ch==13){     // '/n'
    rx_fl=1;
    rx_size = rx_cnt;
    rx_cnt=0;
    return;
}

if(++rx_cnt>=sizeof(rx_buf)){
    err=1;
    rx_cnt=0;
}

}
/****************************************************************/
/*                       Áàéò îòïðàâëåí                         */
/****************************************************************/
void CallBack_TX(void){

tx_fl=1;


}


/****************************************************************/
void Out_Str(char* s){
  while(*s){
    tx_fl=0;
    mUart_Putch(*s++);
    while(!tx_fl);
  };
}
/****************************************************************/

int main (void){

    CLKPR=(1<<CLKPCE);
    CLKPR=(0<<CLKPCE) | (0<<CLKPS3) | (0<<CLKPS2) | (0<<CLKPS1) | (0<<CLKPS0);
	DDRB = 0x03; 
    MCUCR = (0<<ISC01) | (1<<ISC00); 
	OCR1AH= 0xFF;
	OCR1AL= 0xFF;
    TCCR1B|=(1<<CS10)|(1<<CS12); // Çàïóñòèëè ÑÒÑ.
    TIMSK1|=(1<<TOIE1); // Ðàçðåøàåì ïðåðûâàíèå ïî ñîâïàäåíèþ.
	ADMUX=0x05; // ÀÖÏ íà ïÿòûé âõîä
	ADCSRB|=(1<<ADLAR);
	ADCSRA|=(1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);
	ADCH = 20;
    sei();
	mUart_Init();


while (1) {

if(err) {    // Bufer overflow
            err=0;
            // Send error message 
}
if(send) {  
			sprintf (res, "%s %d", "L=", light);  
        	Out_Str(res); mUart_Putch(0x0D);
			send=0;
}
}
}
Изображение
И ты врёшь!!! © Vladisman
Изображение
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

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

Сообщение Gudd-Head »

просто КОТ писал(а):Вопрос -- что не так
Да всё так. Sprintf занимает дофига места.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Реклама
Аватара пользователя
просто КОТ
Друг Кота
Сообщения: 12364
Зарегистрирован: Пт дек 17, 2010 15:07:50
Откуда: Крымский Федеральный Округ
Контактная информация:

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

Сообщение просто КОТ »

Ладненько, тогда к вопросу нумер два. Как быть?
Изображение
И ты врёшь!!! © Vladisman
Изображение
Реклама
Аватара пользователя
ks0
Прорезались зубы
Сообщения: 238
Зарегистрирован: Чт фев 28, 2013 14:16:10

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

Сообщение ks0 »

Банально itoa() использовать
Аватара пользователя
просто КОТ
Друг Кота
Сообщения: 12364
Зарегистрирован: Пт дек 17, 2010 15:07:50
Откуда: Крымский Федеральный Округ
Контактная информация:

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

Сообщение просто КОТ »

Эм... Википедия сказала, что itoa принимает передаваемое целое число input и конвертирует его в число в основании корня radix. Полученное число (последовательность цифр основания radix) записывается в буфер вывода buffer. И я это совсем не понял. Какой корень, какое основание?
Изображение
И ты врёшь!!! © Vladisman
Изображение
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18647
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

просто КОТ писал(а):sprintf (res, "%s %d", "L=", light);
во-первых, так не надо делать. надо делать так: sprintf (res, "L= %d", light);
во-вторых, sprintf сожрет минимум 1,5 килобайта памяти. ну, 1,2 килобайта, если повезет. поэтому обходитесь itoa
в-третьих, можно попытаться уменьшить прожорливсть sprintf-а за счет отказа от некоторых возможностей при помощи опции компилятора -Wl,-u,vfprintf -lprintf_min подробнее читайте здесь: http://www.simple-devices.ru/attachment ... 1-2010.pdf
в-четрвертых, про itoa можно прочесть здесь: http://www.simple-devices.ru/attachment ... 2_2010.pdf
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
Apparatchik
Держит паяльник хвостом
Сообщения: 908
Зарегистрирован: Вс май 23, 2010 13:55:42
Откуда: Украина, Александрия

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

Сообщение Apparatchik »

просто КОТ писал(а):Эм... Википедия сказала
Там же в википедии в низу есть реализация попроще
Спойлер

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

/* itoa:  конвертируем n в символы в s */
void itoa(int n, char s[]) {
	int i, sign;
	char c;

	if ((sign = n) < 0) /* записываем знак */
		n = -n; /* делаем n положительным числом */
	i = 0;
	do { /* генерируем цифры в обратном порядке */
		s[i++] = n % 10 + '0'; /* берем следующую цифру */
	} while ((n /= 10) > 0); /* удаляем */
	if (sign < 0)
		s[i++] = '-';
	s[i] = '\0';

	/*переворачиваем строку*/
	for (i = 0, sign = strlen(s) - 1; i < sign; i++, sign--) {
		c = s[i];
		s[i] = s[sign];
		s[sign] = c;
	}
}
«И всё-таки она вертится!»
Аватара пользователя
просто КОТ
Друг Кота
Сообщения: 12364
Зарегистрирован: Пт дек 17, 2010 15:07:50
Откуда: Крымский Федеральный Округ
Контактная информация:

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

Сообщение просто КОТ »

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

if(send) { 
         itoa (light, res, 10);
		 res[4]='L';
		 res[3]='=';
         Out_Str(res); mUart_Putch(0x0D);
         send=0;
}
Так стало слегка лучше. выводит значение light. Но совершенно игнорирует L=
Изображение
И ты врёшь!!! © Vladisman
Изображение
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

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

Сообщение WiseLord »

Ерунда какая-то написана.
Допустим, ваш ligth = 5;
Тогда после itoa в строке res будет "5". Т.е., res[0] = '5', а res[1] = '\0'. Это и будет выводиться, и по барабану, что вы там пишете в остальные байты массива res (тем более, не в нужном порядке), так как символ конца строки - в позиции [1].
Можно попробовать со смещением писать:

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

res[0]='L';
res[1]='=';
itoa (light, &res[2], 10); // Или itoa (light, res + 2, 10); - должно записать в res, начиная с res[2]
, но надо проверять, не будет ли ошибки.
Аватара пользователя
ks0
Прорезались зубы
Сообщения: 238
Зарегистрирован: Чт фев 28, 2013 14:16:10

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

Сообщение ks0 »

Да отдельно строки вывести, чтоб не скливать их

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

Out_Str("L=");
Out_Str(res);
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18647
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

однахрень не заменяет другую. надо делать так:

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

Out_Str("L=");
Out_Str(res);
Out_Str("\n");
опередил, щустрик :)))
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
просто КОТ
Друг Кота
Сообщения: 12364
Зарегистрирован: Пт дек 17, 2010 15:07:50
Откуда: Крымский Федеральный Округ
Контактная информация:

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

Сообщение просто КОТ »

UART рукописный, причём не мной. Функцию Out_Str не выходит вызывать N раз подряд. Потому вот чего придумал:

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

if(send) { 
itoa (light, res, 10); 
res[2]=res[0];
res[3]=res[1];
res[0]='L';
res[1]='=';
res[4]='\0';
Out_Str(res); mUart_Putch(0x0D);
         send=0;
}
работает.
Изображение
И ты врёшь!!! © Vladisman
Изображение
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18647
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

просто КОТ писал(а):UART рукописный, причём не мной. Функцию Out_Str не выходит вызывать N раз подряд.
это как вообще возможно?! что ж такое нужно написать в функции, чтобы ее нельзя было вызвать несколько раз подряд?! :shock:
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
просто КОТ
Друг Кота
Сообщения: 12364
Зарегистрирован: Пт дек 17, 2010 15:07:50
Откуда: Крымский Федеральный Округ
Контактная информация:

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

Сообщение просто КОТ »

Ну она вроде как сразу после выполнения уходит в себя на некоторое время.
Изображение
И ты врёшь!!! © Vladisman
Изображение
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18647
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

да пусть она хоть в гости уходит - потом-то возвращается? вы же не останавливаете исполнение программы ПОСЛЕ обращения к этой функции? так почему в качестве продолжения работы нельзя СНОВА к ней возвратиться? не понимаю... тем более что наверняка отправка в USART у вас идет в главном ЦИКЛЕ, т.е. эта функция так или иначе вызывается МНОГОКРАТНО...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
ks0
Прорезались зубы
Сообщения: 238
Зарегистрирован: Чт фев 28, 2013 14:16:10

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

Сообщение ks0 »

просто КОТ писал(а):UART рукописный, причём не мной. Функцию Out_Str не выходит вызывать N раз подряд.
Эта функция выглядит примерно так

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

void Out_Str(char* p)
{
	while(*p)
	{
		while(!(UCSRA & (1<<UDRE)));
		UDR=*p;
		p++;
	}
}
И усе! Никаким ограничений по несколько раз подряд там неоткуда взяться
Аватара пользователя
paskal
Нашел транзистор. Понюхал.
Сообщения: 160
Зарегистрирован: Пн сен 05, 2011 10:03:06
Откуда: Тула

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

Сообщение paskal »

Помогите справиться с особенностями кейла. Надо перевести программу с асма на Си. МК - AT89S52. В исходной программе было детектирование резета следующим образом: В некоторую определенную область ОЗУ пишется определенная сигнатура. При старте этот кусок памяти проверяется на сравнение с сигнатурой. Если совпадение, то считается что процессор стартовал после подачи резета. Если несовпадение то был старт по включению питания.
Так вот, программа на си при старте заполняет ОЗУ нулями, затирая сигнатуру. Как у Кейла отключить эту фичу?

И второй вопрос.
В исходной программе использовалось очень много битовых флагов. Позволяет ли Си пользоваться битовыми флагами. То есть чтоб на 1 флаг тратился бит, а не байт?
Если бы на станции "Мир" стояли Винды, она бы еще висела и висела...
Ответить

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