Нельзя ли сделать чтоб было как в ассемблере - где хочу, там и вхожу
Считается плохой практикой, но конечно, можно. Гуглите "оператор goto в языке Си".
я сначала представляю как это сделать на ассемблере
Делайте всё, что вы делали обычно на ассемблере,
только внутри
одной функции на Си, никогда не выходя за её пределы — и будем вам "щастье". Это называется "инкапсуляция". А вот практика создания сложных циклов на метках как раз и считается порочной, потому что потом не разобраться в коде.
В применении к конкретному примеру: не надо пытаться входить в середину функции по метке и тем более переходить по ней из одной функции в середину другой. Надо активно
выдумывать новые функции и вызывать их имена (как подпрограммы) из тех мест, где вы обычно делаете переход по метке. В этом случае goto рассасывается и становится не нужен.
Историческая заметка:
Спойлер
В паскале были процедуры и функции — те и другие являлись подпрограммами, у кого-то были возращаемые значения и параметры, а у кого-то нет. Понятно, что весь этот набор сводится к одним только функциям, поэтому в Си только они и есть.
После этого у вас 100% возникнет вопрос «как сохранять переменные при смене функций». В языке Си вам придётся делать глобальные переменные или структуры и передавать указатели на них в параметры функций. В С++ можно создавать класс: всем функциям этого класса видны все переменные своего класса.
Кусочек вашего примера на упрощённом псевдокоде, похожем на С++:
Спойлер
Код: Выделить всё
struct MyObjects // во множественном числе, потому что это ещё не сам объект, а их тип.
{
MyObjects() // конструктор, вызывается автоматически при создании объекта класса
{
setup();
}
protected:
void setup();
private:
// описание всех переменных, например "int DDRB;"
public:
void my_function(); // доступные для вызова снаружи функции класса (его интерфейс).
}
; // здесь кое-что новое для вас: точка с запятой после фигурной скобки оканчивает класс.
void MyObjects::setup()
{
DDRB |= (1 << sdata)|(1 << sclock)|(1 << latch);
DDRB &= ~(1 << rdata);
}
void MyObjects::my_function()
{
// do something wrong, fix it and do something again :)
}
int main(/* параметры главной функции не используем, просто опишем их тип */int, char*[] )
{
MyObjects object_one;
MyObjects object_two;
// всё: setup вызван у обоих объектов автоматически и оба объекта — независимые.
// можно создавать свои функции и вызывать их так: object_one.my_function();
// глобальная область видимости при этом остаётся чистая, а каждый объект имеет
// по своему набору переменных в памяти.
return 0;
}
Добавлено after 13 minutes 40 seconds:
добавлено: если есть сложности с чтением кода или проблемы зрением, то возьмите Far Manager версии 1.xx (не 2 и не 3), найдите к нему плагин HighLighter и покрасьте себе код по-цветастее, редактируя настройки этого плагина в его папочке и каждый раз перезапуская Far Manager. В редакторе всё станет красивое, а компилировать можно из командной строки.