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

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить
Друг Кота
Сообщения: 4583
Зарегистрирован: Вс дек 05, 2010 06:10:34
Откуда: ЮВ

Сообщение HHIMERA »

Аlex писал(а): Не все компиляторы Вам "скажут спасибо" за всяческие сдвиги, умножения, деления, .... А с указателем, Вы по байтикам работаете с переменной.
Точно так же... не все компиляторы Вам "скажут спасибо" за указатели в критических секциях... А вот сдвиги могут оказаться там к месту...
"Я не даю готовых решений, я заставляю думать!"(С)
Реклама
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

Ну... причём тут критические секции ? В них вообще на что угодно компилятор может "огорчиться", тем более если не понимаешь, что делаешь, как в соседней ветке про недобиблиотеку с портами... :))
А для перекидывания 2-х байт из одного места в другое с помощью сдвигов и умножений - явно неоправданный метод, чего не скажешь про указатели. Потому, что всяческие сдвиги не каждый компилятор адекватно развернёт. Какой то и на самом деле будет двигать :(
Контактная информация:
Реклама
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень

Сообщение vitalik_1984 »

blackx писал(а):Инклюдить нужно только заголовочные файлы, "*.c" уберите.
Я так думаю, что проблема не в том, что не то включено, а в том что идет повторное объявление функции. О чем вежливо , но настойчиво предупреждает препроцессор компилятора. Нужно исключить все повторяющиеся объявления из библиотек.
К примеру в модуле про SPI описать только функции, связанные с этой возможностью Мк, в модуле Usart описать только функции Usart.
Возможно при переносе в библиотеку случайно скопировали лишнее, вот вам и пишет такую ошибку.
Еще как вариант- возможно вы подключаете модуль, в котором уже есть функции с таким же именем, поэтому он не знает что с ними делать.

А вообще что это еще за static void такой? Конкретно пустой тип данных? Уберите static.
Контактная информация:
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1518
Зарегистрирован: Пт дек 28, 2012 21:56:46
Откуда: St. Petersburg

Сообщение blackx »

vitalik_1984 писал(а):А вообще что это еще за static void такой?
А это уже что-то из джавы :)))
Изображение only pure true norwegian blackx Изображение
Реклама
Эиком - электронные компоненты и радиодетали
Потрогал лапой паяльник
Сообщения: 303
Зарегистрирован: Сб янв 08, 2011 13:48:41

Сообщение спящий »

Аlex писал(а):Интересно..., библиотеки создавать научился, а подключать - нет... :)))
Курим - Как оформлять модули
Как я понял надо просто создать файл h,записать туда все функции с .С и подключить.h файл.

Чет непомогло.
Я просто хочу 1н текс разбить на 3 файла,чтобы проще работать.Одним файлом работает программа,начинаю разбивать на 3 нет:

Спойлер#include "stm32l1xx.h"
#include "stdio.h"


#define CMD0 (0x40+0) /* GO_IDLE_STATE */
#define CMD1 (0x40+1) /* SEND_OP_COND (MMC) */
#define ACMD41 (0xC0+41) /* SEND_OP_COND (SDC) */
#define CMD8 (0x40+8) /* SEND_IF_COND */
#define CMD9 (0x40+9) /* SEND_CSD */
#define CMD10 (0x40+10) /* SEND_CID */
#define CMD12 (0x40+12) /* STOP_TRANSMISSION */
#define ACMD13 (0xC0+13) /* SD_STATUS (SDC) */
#define CMD16 (0x40+16) /* SET_BLOCKLEN */
#define CMD17 (0x40+17) /* READ_SINGLE_BLOCK */
#define CMD18 (0x40+18) /* READ_MULTIPLE_BLOCK */
#define CMD23 (0x40+23) /* SET_BLOCK_COUNT (MMC) */
#define ACMD23 (0xC0+23) /* SET_WR_BLK_ERASE_COUNT (SDC) */
#define CMD24 (0x40+24) /* WRITE_BLOCK */
#define CMD25 (0x40+25) /* WRITE_MULTIPLE_BLOCK */
#define CMD55 (0x40+55) /* APP_CMD */
#define CMD58 (0x40+58) /* READ_OCR */



uint8_t temp,res,i;






//отправка числа
static
void xmit_spi(uint8_t xmit_data)
{
SPI1->DR = xmit_data; //Пишем в буфер передатчика SPI1. После этого стартует обмен данными
//отправка числа
while (!(SPI1->SR & SPI_SR_TXE)); //убедиться, что предыдущая передача завершена


}


//прием числа
static
char rcvr_spi(void)
{uint8_t res;
SPI1->DR = 0xff; //Пишем в буфер передатчика SPI1. После этого стартует обмен данными
while (!(SPI1->SR & SPI_SR_TXE)); //убедиться, что предыдущая передача завершена

//прием числа
while(!(SPI1->SR & SPI_SR_RXNE)); //Ожидаем окончания приема данных модулем SPI1 (RXNE =1 - приемный буфер содержит данные)
res= SPI1->DR;

return res;
}



static void send_cmd(char cmd,char arg)
{


/* Send command packet */
xmit_spi(cmd); /* Start + Command index */
xmit_spi((char)(arg >> 24)); /* Argument[31..24] */
xmit_spi((char)(arg >> 16)); /* Argument[23..16] */
xmit_spi((char)(arg >> 8)); /* Argument[15..8] */
xmit_spi((char)arg); /* Argument[7..0] */
xmit_spi(0x95);

}










int main()
{ //настройка портов под SPI

RCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN; //Тактирование портов A, B
//Линини SPI1 (Master)
//PA12(MOSI), PA11(MISO), PA5(SCK), PA4(NSS) - AF, Push-Pull, AF5(SPI1)
GPIOA->MODER |= GPIO_MODER_MODER12_1 | GPIO_MODER_MODER11_1 | GPIO_MODER_MODER5_1 | GPIO_MODER_MODER4_1; //Alternate function
GPIOA->OTYPER &= ~(GPIO_OTYPER_OT_12 | GPIO_OTYPER_OT_11 | GPIO_OTYPER_OT_5 | GPIO_OTYPER_OT_4); //Push-Pull
GPIOA->AFR[1] |= (5<<16 | 5<<12); //PA12 = AF5, PA11 = AF5
GPIOA->AFR[0] |= (5<<20 | 5<<16); //PA5 = AF5, PA4 = AF5

//настройка SPI

RCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN; //Тактирование портов A, B
//Линини SPI1 (Master)
//PA12(MOSI), PA11(MISO), PA5(SCK), PA4(NSS) - AF, Push-Pull, AF5(SPI1)
GPIOA->MODER |= GPIO_MODER_MODER12_1 | GPIO_MODER_MODER11_1 | GPIO_MODER_MODER5_1 | GPIO_MODER_MODER4_1; //Alternate function
GPIOA->OTYPER &= ~(GPIO_OTYPER_OT_12 | GPIO_OTYPER_OT_11 | GPIO_OTYPER_OT_5 | GPIO_OTYPER_OT_4); //Push-Pull
GPIOA->AFR[1] |= (5<<16 | 5<<12); //PA12 = AF5, PA11 = AF5
GPIOA->AFR[0] |= (5<<20 | 5<<16); //PA5 = AF5, PA4 = AF5


//LED
GPIOB->MODER |= GPIO_MODER_MODER6_0 | GPIO_MODER_MODER7_0; //PB6, PB7 - GP Output
GPIOB->OTYPER &= ~(GPIO_OTYPER_OT_6 | GPIO_OTYPER_OT_7); //PB6, PB7 - Push-Pull
GPIOB->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR6 | GPIO_OSPEEDER_OSPEEDR7; //40 MHz
GPIOB->PUPDR &= ~(GPIO_PUPDR_PUPDR6 | GPIO_PUPDR_PUPDR7); //No pull

/*Настройка SPI1 (Master)
8 бит данных, MSB передается первым, программный режим управления NSS,
вывод NSS (PA4) разрешено использовать в качестве выхода*/
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; //Тактирование модуля SPI1

SPI1->CR1 &= ~SPI_CR1_CPOL; //Полярность тактового сигнала
SPI1->CR1 &= ~SPI_CR1_CPHA; //Фаза тактового сигнала
SPI1->CR1 &= ~SPI_CR1_DFF; //8 бит данных
SPI1->CR1 &= ~SPI_CR1_LSBFIRST; //MSB передается первым


SPI1->CR2 = 0; //Вывод NSS - выход управления slave select
SPI1->CR1 |= SPI_CR1_MSTR; //Режим Master
SPI1->CR1 |= SPI_CR1_BR; //Baud rate = Fpclk/256
SPI1->CR1 |= SPI_CR1_SSM; //Программный режим NSS
SPI1->CR1 |= SPI_CR1_SSI; //Аналогично состоянию, когда на входе NSS высокий уровень
SPI1->CR1 |= SPI_CR1_SPE; //Включаем SPI1


for (int n = 7; n; n--) xmit_spi(0xff); /* 80 dummy clocks */



for (int n = 7; n; n--) xmit_spi(0xff); /* 80 dummy clocks */



send_cmd(CMD0,0);
while(!(res==1)){
SPI1->DR = 0xff;
res=rcvr_spi();
if (i>10)
{send_cmd(CMD0,0);
i=0;
}
i++;
putchar(res);
}
send_cmd(CMD1,0);
while(!(res==0)){
SPI1->DR = 0xff;
res=rcvr_spi();
if (i>20)
{send_cmd(CMD1,0);
i=0;
}
i++;
putchar(res);
}






xmit_spi(CMD18);
xmit_spi(0);
xmit_spi(0);
xmit_spi(0);
xmit_spi(0);
xmit_spi(0xff);
while(1){
res=rcvr_spi();
if(res!=0Xff){if(res!=0X0){
putchar(res);}

}
}
}
В одной статье прочитал что можно подключать любые файлы .с в том числе,тоесть по большому счету .h и ненужна,может бы ть косяк с функциями?

static void xmit_spi(uint8_t xmit_data) у меня они все такого вида, а переменные нужно указывать static и т.д.?
Реклама
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1518
Зарегистрирован: Пт дек 28, 2012 21:56:46
Откуда: St. Petersburg

Сообщение blackx »

Вот так попробуйте:
Спойлер

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

================
file: spi_transmitter.h
================

#include "stm32l1xx.h"
#include "stdio.h"


#define CMD0	(0x40+0)	/* GO_IDLE_STATE */
#define CMD1	(0x40+1)	/* SEND_OP_COND (MMC) */
#define ACMD41	(0xC0+41)	/* SEND_OP_COND (SDC) */
#define CMD8	(0x40+8)	/* SEND_IF_COND */
#define CMD9	(0x40+9)	/* SEND_CSD */
#define CMD10	(0x40+10)	/* SEND_CID */
#define CMD12	(0x40+12)	/* STOP_TRANSMISSION */
#define ACMD13	(0xC0+13)	/* SD_STATUS (SDC) */
#define CMD16	(0x40+16)	/* SET_BLOCKLEN */
#define CMD17	(0x40+17)	/* READ_SINGLE_BLOCK */
#define CMD18	(0x40+18)	/* READ_MULTIPLE_BLOCK */
#define CMD23	(0x40+23)	/* SET_BLOCK_COUNT (MMC) */
#define ACMD23	(0xC0+23)	/* SET_WR_BLK_ERASE_COUNT (SDC) */
#define CMD24	(0x40+24)	/* WRITE_BLOCK */
#define CMD25	(0x40+25)	/* WRITE_MULTIPLE_BLOCK */
#define CMD55	(0x40+55)	/* APP_CMD */
#define CMD58	(0x40+58)	/* READ_OCR */



extern uint8_t temp,res,i;

//отправка числа
void xmit_spi(uint8_t xmit_data);

//прием числа
char rcvr_spi(void);


void send_cmd(char cmd,char arg);

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

================
file: spi_transmitter.c
================


//отправка числа
void xmit_spi(uint8_t xmit_data)
{
SPI1->DR = xmit_data; //Пишем в буфер передатчика SPI1. После этого стартует обмен данными
//отправка числа 
while (!(SPI1->SR & SPI_SR_TXE)); //убедиться, что предыдущая передача завершена
}


//прием числа
char rcvr_spi(void)
{uint8_t res;
SPI1->DR = 0xff; //Пишем в буфер передатчика SPI1. После этого стартует обмен данными
while (!(SPI1->SR & SPI_SR_TXE)); //убедиться, что предыдущая передача завершена

//прием числа
while(!(SPI1->SR & SPI_SR_RXNE)); //Ожидаем окончания приема данных модулем SPI1 (RXNE =1 - приемный буфер содержит данные)
res= SPI1->DR;

return res;
}



void send_cmd(char cmd,char arg)
{


/* Send command packet */
xmit_spi(cmd);	 /* Start + Command index */
xmit_spi((char)(arg >> 24));	 /* Argument[31..24] */
xmit_spi((char)(arg >> 16));	 /* Argument[23..16] */
xmit_spi((char)(arg >> );	 /* Argument[15..8] */
xmit_spi((char)arg);	 /* Argument[7..0] */
xmit_spi(0x95);

}

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

================
file: main.c
================

#include "stm32l1xx.h"
#include "stdio.h"
#include "spi_transmitter.h"


int main()
{ //настройка портов под SPI

RCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN; //Тактирование портов A, B
//Линини SPI1 (Master)
//PA12(MOSI), PA11(MISO), PA5(SCK), PA4(NSS) - AF, Push-Pull, AF5(SPI1)
GPIOA->MODER |= GPIO_MODER_MODER12_1 | GPIO_MODER_MODER11_1 | GPIO_MODER_MODER5_1 | GPIO_MODER_MODER4_1; //Alternate function
GPIOA->OTYPER &= ~(GPIO_OTYPER_OT_12 | GPIO_OTYPER_OT_11 | GPIO_OTYPER_OT_5 | GPIO_OTYPER_OT_4); //Push-Pull
GPIOA->AFR[1] |= (5<<16 | 5<<12); //PA12 = AF5, PA11 = AF5
GPIOA->AFR[0] |= (5<<20 | 5<<16); //PA5 = AF5, PA4 = AF5

//настройка SPI

RCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN; //Тактирование портов A, B
//Линини SPI1 (Master)
//PA12(MOSI), PA11(MISO), PA5(SCK), PA4(NSS) - AF, Push-Pull, AF5(SPI1)
GPIOA->MODER |= GPIO_MODER_MODER12_1 | GPIO_MODER_MODER11_1 | GPIO_MODER_MODER5_1 | GPIO_MODER_MODER4_1; //Alternate function
GPIOA->OTYPER &= ~(GPIO_OTYPER_OT_12 | GPIO_OTYPER_OT_11 | GPIO_OTYPER_OT_5 | GPIO_OTYPER_OT_4); //Push-Pull
GPIOA->AFR[1] |= (5<<16 | 5<<12); //PA12 = AF5, PA11 = AF5
GPIOA->AFR[0] |= (5<<20 | 5<<16); //PA5 = AF5, PA4 = AF5


//LED
GPIOB->MODER |= GPIO_MODER_MODER6_0 | GPIO_MODER_MODER7_0; //PB6, PB7 - GP Output
GPIOB->OTYPER &= ~(GPIO_OTYPER_OT_6 | GPIO_OTYPER_OT_7); //PB6, PB7 - Push-Pull
GPIOB->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR6 | GPIO_OSPEEDER_OSPEEDR7; //40 MHz
GPIOB->PUPDR &= ~(GPIO_PUPDR_PUPDR6 | GPIO_PUPDR_PUPDR7); //No pull

/*Настройка SPI1 (Master)
8 бит данных, MSB передается первым, программный режим управления NSS,
вывод NSS (PA4) разрешено использовать в качестве выхода*/
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; //Тактирование модуля SPI1

SPI1->CR1 &= ~SPI_CR1_CPOL; //Полярность тактового сигнала
SPI1->CR1 &= ~SPI_CR1_CPHA; //Фаза тактового сигнала
SPI1->CR1 &= ~SPI_CR1_DFF; //8 бит данных
SPI1->CR1 &= ~SPI_CR1_LSBFIRST; //MSB передается первым


SPI1->CR2 = 0; //Вывод NSS - выход управления slave select
SPI1->CR1 |= SPI_CR1_MSTR; //Режим Master
SPI1->CR1 |= SPI_CR1_BR; //Baud rate = Fpclk/256
SPI1->CR1 |= SPI_CR1_SSM; //Программный режим NSS
SPI1->CR1 |= SPI_CR1_SSI; //Аналогично состоянию, когда на входе NSS высокий уровень
SPI1->CR1 |= SPI_CR1_SPE; //Включаем SPI1


for (int n = 7; n; n--) xmit_spi(0xff);	/* 80 dummy clocks */

for (int n = 7; n; n--) xmit_spi(0xff);	/* 80 dummy clocks */

send_cmd(CMD0,0);
while(!(res==1)){
SPI1->DR = 0xff;
res=rcvr_spi();
if (i>10)
{send_cmd(CMD0,0);
i=0;
} 
i++; 
putchar(res);
}
send_cmd(CMD1,0);
while(!(res==0)){
SPI1->DR = 0xff;
res=rcvr_spi();
if (i>20)
{send_cmd(CMD1,0);
i=0;
} 
i++; 
putchar(res);
}


xmit_spi(CMD18);
xmit_spi(0);
xmit_spi(0);
xmit_spi(0);
xmit_spi(0);
xmit_spi(0xff);
while(1){
res=rcvr_spi();
if(res!=0Xff){if(res!=0X0){
putchar(res);}

} 
}
}
PS static-и убрал. Если не знаете, зачем их писать - не пишите. Я вот например не знаю :).
Изображение only pure true norwegian blackx Изображение
Реклама
Встал на лапы
Аватара пользователя
Сообщения: 135
Зарегистрирован: Вт фев 21, 2012 20:42:26
Откуда: Санкт-Петербург, Россия, Земля

Сообщение U235 »

vitalik_1984 писал(а):А вообще что это еще за static void такой? Конкретно пустой тип данных? Уберите static.
Вы о функциях вида

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

static void pover_on (void);
Нормальное объявление функции с областью видимости, ограниченной файлом, в котором функция определена. Очень удобный способ избежать некоторых случайных ошибок.
А из наших труб идет необычный дым. Стой! Опасная зона! Работа мозга!...
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1518
Зарегистрирован: Пт дек 28, 2012 21:56:46
Откуда: St. Petersburg

Сообщение blackx »

А зачем это? Чтобы нельзя было заинклюдить c-файл и вызывать функцию из него? Обычно такие функции в *.h файле просто не описываются и все.
Спойлер

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

==============
test.h
==============

static void destroy();

==============
test.c
==============
#include "test.h"

static void destroy()
{
    // ... perform "rm -rf /"
}

==============
main.c
==============
#include "test.c"

int main(void)
{
    destroy();
}

Изображение only pure true norwegian blackx Изображение
Опытный кот
Аватара пользователя
Сообщения: 736
Зарегистрирован: Пн янв 10, 2011 03:06:36
Откуда: Ростов-на-Дону

Сообщение Goldsmith »

blackx писал(а):А зачем это? Чтобы нельзя было заинклюдить c-файл и вызывать функцию из него? Обычно такие функции в *.h файле просто не описываются и все.
Этого мало.

Если функция объявлена как глобальная (т. е. ее область видимости не ограничена файлом), ее точка входа присутствует в таблице символов объектного файла, и она может быть вызвана извне независимо от того, описали ее в заголовке или нет. Это и есть потенциальный источник ошибок, о которых говорил U235. Поэтому лучше все-таки не выбрасывать из программы ключевые слова, назначение которых не поняли (так можно слишком далеко зайти), а разобраться в основах C, благо язык простейший.
Любой дурак может писать код. Настоящий профессионал - это тот, кто способен постоянно создавать продукт высокого качества, укладываясь при этом в бюджет.
J. Ganssle
Контактная информация:
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень

Сообщение vitalik_1984 »

Goldsmith писал(а): Поэтому лучше все-таки не выбрасывать из программы ключевые слова, назначение которых не поняли (так можно слишком далеко зайти), а разобраться в основах C, благо язык простейший.
По ссылке что указал ALEX что то не применено это ключевое слово как тут учиться?
Спойлер

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

//******************************************************************************
//  Секция описания функций (сначала глобальных, потом локальных)
//******************************************************************************
 
void global_func1 (void)
{
    ...;
}
 
void global_func1 (void)
{
    ...;
}
 
...
 
void local_func1 (void)
{
    ...;
}
 
void local_func1 (void)
{
    ...;
}
 
... 
Контактная информация:
Встал на лапы
Аватара пользователя
Сообщения: 135
Зарегистрирован: Вт фев 21, 2012 20:42:26
Откуда: Санкт-Петербург, Россия, Земля

Сообщение U235 »

Зачем применять static к функциям я узнал из документации к Open Watcom.
Use static for Most Functions
Most functions do not need to be called from routines outside of the current module. Yet, if the keyword static is not used in the function declaration, then the function is automatically given external linkage. This can lead to a proliferation of external symbols, which may cause naming conflicts. Also, some linking programs may impose limitations.

Only those functions that must have external linkage should be made external. All other definitions of functions should start with the keyword static.

It also is a good idea to start definitions for external functions with the keyword extern, even though it is the default case.
То же самое справедливо и для переменных, определённых вне функций.
А из наших труб идет необычный дым. Стой! Опасная зона! Работа мозга!...
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1518
Зарегистрирован: Пт дек 28, 2012 21:56:46
Откуда: St. Petersburg

Сообщение blackx »

А скажите, есть ли смысл в целях оптимизации скорости объявлять переменные внутри функций как static?
Изображение only pure true norwegian blackx Изображение
Опытный кот
Аватара пользователя
Сообщения: 736
Зарегистрирован: Пн янв 10, 2011 03:06:36
Откуда: Ростов-на-Дону

Сообщение Goldsmith »

vitalik_1984 писал(а):По ссылке что указал ALEX что то не применено это ключевое слово как тут учиться?
Так ведь имеется великое множество хороших источников помимо ссылок, что указал ALEX. Там и найдете все необходимое.
blackx писал(а):А скажите, есть ли смысл в целях оптимизации скорости объявлять переменные внутри функций как static?
Вряд ли результат такой оптимизации будет так легко заметить. А вот реентерабельной такая функция быть сразу перестанет (впрочем, для процессоров начального уровня и самых простых программ это может быть неактуальным).

Обычно статические локальные переменные применяются в случаях, когда их значение должно сохраняться между вызовами функции. В частности, это необходимо при использовании некоторых реализаций механизма сопрограмм, например, известный Protothreads и подобные.
Любой дурак может писать код. Настоящий профессионал - это тот, кто способен постоянно создавать продукт высокого качества, укладываясь при этом в бюджет.
J. Ganssle
Контактная информация:
Встал на лапы
Аватара пользователя
Сообщения: 135
Зарегистрирован: Вт фев 21, 2012 20:42:26
Откуда: Санкт-Петербург, Россия, Земля

Сообщение U235 »

Тут действие другое. Если переменная внутри функции объявлена как static, то она сохраняет значение между вызовами этой функции. Без static значение переменной в момент вызова функции неопределённо.

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

int foo(void)
{
    static int i=4;  // Инициализация происходит только при первом вызове функции.

    if (!i) return 0;
    i--;
    return 1;
}
Первые четыре вызова функция вернёт 1, все последующие будет возвращать 0.
Последний раз редактировалось U235 Пн фев 04, 2013 18:59:32, всего редактировалось 1 раз.
А из наших труб идет необычный дым. Стой! Опасная зона! Работа мозга!...
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1518
Зарегистрирован: Пт дек 28, 2012 21:56:46
Откуда: St. Petersburg

Сообщение blackx »

Да это понятно. Переменная на этапе инициализации занимает свое место в стеке, как будто глобальная, но доступна только внутри функции.
Вопрос в том, что, если функция имеет несколько переменных, и вызывается циклически много раз, будет ли эффективным объявить ее переменные статичными (функция при вызове каждый раз заново инициализирует все переменные)?
Изображение only pure true norwegian blackx Изображение
Встал на лапы
Аватара пользователя
Сообщения: 135
Зарегистрирован: Вт фев 21, 2012 20:42:26
Откуда: Санкт-Петербург, Россия, Земля

Сообщение U235 »

blackx писал(а):Вопрос в том, что, если функция имеет несколько переменных, и вызывается циклически много раз, будет ли эффективным объявить ее переменные статичными ?
В некоторых компиляторах может быть наоборот. Например, WinAvr старается переменные функции разместить в регистрах. А так ему придётся и с памятью возиться и с регистрами.
А из наших труб идет необычный дым. Стой! Опасная зона! Работа мозга!...
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень

Сообщение vitalik_1984 »

U235 писал(а):
Only those functions that must have external linkage should be made external.
В таком случае зачем нужно использовать static в данном конкретном случае? Ведь как раз эти функции используются вне данного модуля.
Контактная информация:
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1518
Зарегистрирован: Пт дек 28, 2012 21:56:46
Откуда: St. Petersburg

Сообщение blackx »

Да, у спящего компилятор должен выдать ошибку на это.
И я не очень согласен с тем утверждением, что большинство функций - внутренние, у меня обычно наоборот :)

U235, спасибо, буду курить дизасм :))).
Изображение only pure true norwegian blackx Изображение
Встал на лапы
Аватара пользователя
Сообщения: 135
Зарегистрирован: Вт фев 21, 2012 20:42:26
Откуда: Санкт-Петербург, Россия, Земля

Сообщение U235 »

vitalik_1984 писал(а):В таком случае зачем нужно использовать static в данном конкретном случае? Ведь как раз эти функции используются вне данного модуля.
Вы вроде просто о static void спрашивали. А в случае с подключением *.c файлов это действительно не имеет смысла.
А из наших труб идет необычный дым. Стой! Опасная зона! Работа мозга!...
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень

Сообщение vitalik_1984 »

U235 писал(а):Вы вроде просто о static void спрашивали. А в случае с подключением *.c файлов это действительно не имеет смысла.
Это не я спрашивал, это человек спрашивал про модули, я просто сказал, что он там не нужен. Может не совсем понимая что это значит.Поняв для чего это я задал другой вопрос.

PS никто не заметил, что в коде у спрашивающего полная каша? В модуле sd_spi_stm32.c происходит объявление функции модуля usb.c еще куча всего прелестного.
Контактная информация:
Ответить

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