Главная страница Случайная страница Разделы сайта АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
💸 Как сделать бизнес проще, а карман толще?
Тот, кто работает в сфере услуг, знает — без ведения записи клиентов никуда. Мало того, что нужно видеть свое раписание, но и напоминать клиентам о визитах тоже.
Проблема в том, что средняя цена по рынку за такой сервис — 800 руб/мес или почти 15 000 руб за год. И это минимальный функционал.
Нашли самый бюджетный и оптимальный вариант: сервис VisitTime.⚡️ Для новых пользователей первый месяц бесплатно. А далее 290 руб/мес, это в 3 раза дешевле аналогов. За эту цену доступен весь функционал: напоминание о визитах, чаевые, предоплаты, общение с клиентами, переносы записей и так далее. ✅ Уйма гибких настроек, которые помогут вам зарабатывать больше и забыть про чувство «что-то мне нужно было сделать». Сомневаетесь? нажмите на текст, запустите чат-бота и убедитесь во всем сами! Указатели на структуры
Для иллюстрации некоторых моментов, касающихся указателей на структуры и массивов структур, перепишем программу подсчета ключевых слов, пользуясь для получения элементов массива вместо индексов указателями. Внешнее объявление массива keytab остается без изменения, a main и binsearch нужно модифицировать. #include < stdio.h> #include < ctype.h> #include < string.h> #define MAXWORD 100
int getword(char *, int); struct key *binsearch(char *, struct key *, int);
/* подсчет ключевых слов Си: версия с указателями */ main() { char word[MAXWORD]; struct key *p; while (getword(word, MAXWORD)! = EOF) if (isalpha(word[0])) if ((p = binsearch(word, keytab, NKEYS))! = NULL) p-> count++; for (p = keytab; p < keytab + NKEYS; p++) if (p-> count > 0) printf(" %4d %s\n", p-> count, p-> word); return 0; }
/* binsearch: найти слово word в tab[0]...tab[n-1] */ struct key *binsearch(char *word, struct key *tab, int n) { int cond; struct key *low = & tab[0]; struct key *high = & tab[n]; struct key *mid; while (low < high) { mid = low + (high - low) / 2; if ((cond = strcmp(word, mid-> word)) < 0) high = mid; else if (cond > 0) low = mid + 1; else return mid; } return NULL; } Некоторые детали этой программы требуют пояснений. Во-первых, описание функции binsearch должно отражать тот факт, что она возвращает указатель на struct key, а не целое, это объявлено как в прототипе функции, так и в функции binsearch. Если binsearch находит слово, то она выдает указатель на него, в противном случае она возвращает NULL. Во-вторых, к элементам keytab доступ в нашей программе осуществляется через указатели. Это потребовало значительных изменений в binsearch. Инициализаторами для low и high теперь служат указатели на начало и на место сразу после конца массива. Вычисление положения среднего элемента с помощью формулы mid = (low + high) / 2 /* НЕВЕРНО */ не годится, поскольку указатели нельзя складывать. Однако к ним можно применить операцию вычитания, и так как high-low есть число элементов, присваивание mid = low + (high-low) / 2 превратит mid в указатель на элемент, лежащий посередине между low и high. Самое важное при переходе на новый вариант программы - сделать так, чтобы не генерировались неправильные указатели и не было попыток обратиться за пределы массива. Проблема в том, что и & tab[-1], и & tab[n] находятся вне границ массива. Первый адрес определенно неверен, нельзя также осуществить доступ и по второму адресу. По правилам языка, однако, гарантируется, что адрес ячейки памяти, следующей сразу за концом массива (т. е. & tab[n]), в арифметике с указателями воспринимается правильно. В главной программе main мы написали for (р = keytab; р < keytab + NKEYS; р++) Если p - это указатель на структуру, то при выполнении операций с р учитывается размер структуры. Поэтому р++ увеличит р на такую величину, чтобы выйти на следующий структурный элемент массива, а проверка условия вовремя остановит цикл. Не следует, однако, полагать, что размер структуры равен сумме размеров ее элементов. Вследствие выравнивания объектов разной длины в структуре могут появляться безымянные " дыры". Например, если переменная типа char занимает один байт, а int - четыре байта, то для структуры struct { char с; int i; }; может потребоваться восемь байтов, а не пять. Оператор sizeof возвращает правильное значение. Наконец, несколько слов относительно формата программы. Если функция возвращает значение сложного типа, как, например, в нашем случае она возвращает указатель на структуру: struct key *binsearch(char *word, struct key *tab, int n) то " высмотреть" имя функции оказывается совсем не просто. В подобных случаях иногда пишут так: struct key * binsearch(char *word, struct key *tab, int n) Какой форме отдать предпочтение - дело вкуса. Выберите ту, которая больше всего вам нравится, и придерживайтесь ее.
|