Помогите с подпрограммами на СИ

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
Друг Кота
Сообщения: 13796
Зарегистрирован: Чт сен 20, 2007 14:08:00

Сообщение kalobyte »

в сях есть функции
они могу возвращать результат, могут не возвращать
если не надо ничего возвращать и принимать входящих параметров, то пишется void

например функция, которая генерирует тональный сигнал

void beep(void){
...
}

все функции пишутся вне тела главной функции main
вызываются же внутри главной функции

пример из математики y=x+4

у нас есть 1 входной параметр и 1 выходной
char myfunc(char x){
return x+4;
}

вызываеш ее так
char y;
y = func(2);
значение у у тебя будет 6 и программа будет работать дальше
return пишеш только тогда, когда функция должна вернуть результат и перед ее названием стоит не void
функция так же может возвращать результат, не имея входных параметров

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

много функций могут привести к переполнению стека и неотлавливаемым глюкам или тормозам
поэтому иногда лучше обойтись без функций и написать код 3 раза
Реклама
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2029
Зарегистрирован: Сб ноя 15, 2008 10:09:56
Откуда: г. Тула

Сообщение IfoR »

kalobyte писал(а): если не надо ничего возвращать и принимать входящих параметров, то пишется void

например функция, которая генерирует тональный сигнал

void beep(void){
...
}
Кстати, void можно вобще не писать. Такое действия определяется как void :)

Можно писать так:

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

function ()
{
}
kalobyte писал(а): вызываются же внутри главной функции
Необязательно. Функции можно вызывать откуда угодно, хоть из main(), хоть из другой функции, хоть из самой себя. Лиж бы она или её прототип определена была выше.
kalobyte писал(а):return пишеш только тогда, когда функция должна вернуть результат и перед ее названием стоит не void
Тоже необязательно. return; может вызываться для выхода из функции.
Например:

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

int a;
char rez;

void fun()
{
 a%=10;
 if (!a) return;
 rez++;
}
Тут функция работает с внешними переменными.
Делает она вот что:
1. Записывает в a остаток от деления a на 10, т.е. оставляет в a только первую цифру справа.
2. Если a равно 0, то выйти из функции.
3. Увеличить rez на 1.
kalobyte писал(а):переменные внутри функции действуют только внутри нее
Коректней сказать Автоматические переменные (без модификатора или auto) объявленые внутри блока { } (именно внутри этого блока) действуют только в нём. За пределами блока она уничтожается. Однако, если к переменой добавить модификатор static то она будет действовать везде и не уничтожится никогда, повторно объявлятся она уже не будет. Пишется так например static void x; static int a;
Так же, если объявить авт. переменную внутри блока с таким же именем что и объявленая вне блока, то внутри блока действительной переменной будет та, что объявленна внутри. Если же попытать объявить 2 раза переменую с тем же именем в одном и том же блоке, то это приведёт к ошибке...
Например:

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

 
int fun()
{
 int rez=0;

 int a=1;

 {
  int a=3;
  rez+=a;
 }
 rez+=a;

 return rez;
}
Результатом выполнения будет 4.
kalobyte писал(а): дургими словами - если у тебя уже есть переменная х в основной функции, то ты можеш снова использовать х и они никак не повлияют друг на друга
Опять же... Это смотря как делать. Если ты передаёшь в функцию значение переменной, то саму переменную внешнею изменить нельзя, а вот если передать в функцию адрес переменой то изменятся она будет без проблем. :)

Например:

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

int a;

void fun(int* per)
{
 *per+=10;
}

void main()
{
 a = 7;
 fun(&a);
}
Теперь в a после выполнения функции будет 17. :)
kalobyte писал(а): много функций могут привести к переполнению стека и неотлавливаемым глюкам или тормозам
поэтому иногда лучше обойтись без функций и написать код 3 раза
Обана... Ну это уже не понятно... Если функция не уходит в глубокую рекурсию, то переполнение стека врятли будет, если она нормально исполняется в самом коде. Функция просто распологается в отдельном месте памяти и к ней обращаются из других мест. Она же не копирует себя в память несколько раз. Как раз наоборот, она пишется только один раз. И вобще, почти каждая, кроме системных, команда в С является функцией. И ничего не глючит, не тормозит. Глючить и тормозить она может только из-за неправильного написания или, если она выполняет что-то запредельное для данного МК.
А если же функций столько много и они все используются, что весь кон попросту не влезает, то врятли писание несколько раз кода функции уменьшит размер кода...
Контактная информация:
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18786
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

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

Мой уютный бложик... заходите!
Контактная информация:
SII
Вымогатель припоя
Сообщения: 635
Зарегистрирован: Пт янв 30, 2009 14:50:35
Откуда: Солнечногорск

Сообщение SII »

IfoR писал(а): Обана... Ну это уже не понятно... Если функция не уходит в глубокую рекурсию, то переполнение стека врятли будет, если она нормально исполняется в самом коде. Функция просто распологается в отдельном месте памяти и к ней обращаются из других мест. Она же не копирует себя в память несколько раз. Как раз наоборот, она пишется только один раз.
Локальные переменные функции, если они не объявлены как static, размещаются в стеке. Поэтому стек малого размера может переполнить даже одна-единственная функция, если у неё море локальных переменных. При программировании на ПК об этом обычно не думают, ведь размер стека может теоретически достигать чуть ли не 2 Гбайт на 32-разрядной системе, но в случае с микроконтроллерами помнить про это следует.
Реклама
Эиком - электронные компоненты и радиодетали
Встал на лапы
Аватара пользователя
Сообщения: 99
Зарегистрирован: Сб ноя 29, 2008 19:34:25
Откуда: Нальчик

Сообщение Tigra »

Спасибо за помощь в решении моей проблеммы! Очень приятно,что на этом форуме есть грамотные люди, которым не трудно потратить своё время и поделиться своим опытом.
Реклама
Друг Кота
Сообщения: 13796
Зарегистрирован: Чт сен 20, 2007 14:08:00

Сообщение kalobyte »

IfoR это конечно повышает твое чсв, но автор мог бы и сам прочитать в книге все подробности о реализации функций

в данный момент ему требовался только простой синтаксис и понимание механизма функций в отличии от бейсика, который я и продемонстрировал на примере алгебры
Реклама
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»