Страница 2 из 2

Добавлено: Сб сен 19, 2009 05:42:58
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 раза

Добавлено: Сб сен 19, 2009 06:37:59
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 раза
Обана... Ну это уже не понятно... Если функция не уходит в глубокую рекурсию, то переполнение стека врятли будет, если она нормально исполняется в самом коде. Функция просто распологается в отдельном месте памяти и к ней обращаются из других мест. Она же не копирует себя в память несколько раз. Как раз наоборот, она пишется только один раз. И вобще, почти каждая, кроме системных, команда в С является функцией. И ничего не глючит, не тормозит. Глючить и тормозить она может только из-за неправильного написания или, если она выполняет что-то запредельное для данного МК.
А если же функций столько много и они все используются, что весь кон попросту не влезает, то врятли писание несколько раз кода функции уменьшит размер кода...

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

Добавлено: Сб сен 19, 2009 14:31:18
SII
IfoR писал(а): Обана... Ну это уже не понятно... Если функция не уходит в глубокую рекурсию, то переполнение стека врятли будет, если она нормально исполняется в самом коде. Функция просто распологается в отдельном месте памяти и к ней обращаются из других мест. Она же не копирует себя в память несколько раз. Как раз наоборот, она пишется только один раз.
Локальные переменные функции, если они не объявлены как static, размещаются в стеке. Поэтому стек малого размера может переполнить даже одна-единственная функция, если у неё море локальных переменных. При программировании на ПК об этом обычно не думают, ведь размер стека может теоретически достигать чуть ли не 2 Гбайт на 32-разрядной системе, но в случае с микроконтроллерами помнить про это следует.

Добавлено: Сб сен 19, 2009 14:37:29
Tigra
Спасибо за помощь в решении моей проблеммы! Очень приятно,что на этом форуме есть грамотные люди, которым не трудно потратить своё время и поделиться своим опытом.

Добавлено: Вс сен 20, 2009 07:45:36
kalobyte
IfoR это конечно повышает твое чсв, но автор мог бы и сам прочитать в книге все подробности о реализации функций

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