PINB &= 0b00000000
.char oldState = 0, newState = 0
...
oldState = newState;
newState = PINB & 0b00000001;
if (!newState && oldState) {
// нажатие кнопки зарегистрировано.
// 1. переключить состояние.
// 2. Записать что надо в порт.
// 3. Сделать задержку на дребезг.
}
#include <iostream>
#define CHECK(a,b) \
if ((a) == (b)) \
std::cout << "Equal" << std::endl; \
else std::cout << "Inequal" << std::endl;
int main()
{
for (int i = 0; i < 5; ++i) {
CHECK (i, 2)
}
return 0;
}
int main()
{
for (int i = 0; i < 5; ++i) {
if ((i) == (2))
std::cout << "Equal" << std::endl;
else std::cout << "Inequal" << std::endl;
}
return 0;
}
Inequal
Inequal
Equal
Inequal
Inequal
typedef enum {
LI_A, LI_B, LI_N
} ListIndex;
enum { LEN = 40 };
typedef struct {
Entry* next[LI_N];
char name[LEN];
} Entry;
typedef Entry* PEntry;
PEntry heads[LI_N], tails[LI_N]; // считаем, что = NULL
int isIn(ListIndex aIndex, Entry* aEntry)
{
return (aEntry->next[aIndex] || tails[aIndex] == aEntry);
}
void addExisting(ListIndex aIndex, Entry* aEntry)
{
/* Уже есть? Поскольку такой код чреват ошибками, лучше всё же проверить */
if (isIn(aIndex, aEntry))
return;
if (tails[aIndex]) {
tails[aIndex]->next = aEntry;
tails[aIndex] = aEntry;
} else {
heads[aIndex] = tails[aIndex] = aEntry;
}
}
Entry* addNew(ListIndex aIndex, char* aName)
{
int i;
Entry* newEntry = (Entry*)malloc(sizeof(Entry));
strncpy(entry->name, aName, LEN);
entry->name[LEN-1] = '\0';
for (i = 0; i < LI_N, ++i)
entry->next[i] = NULL;
addExisting(aIndex, entry);
return entry;
}
/* closure — т.н. замыкание, передача контекста, из которого была
вызвана функция, вызывающая callback */
typedef void(*ListCallback)(Entry* aEntry, void* aClosure);
void traverseList(ListIndex aIndex, ListCallback aCallback, void* aClosure)
{
Entry* entry = heads[aIndex];
while (entry) {
aCallback(aEntry, aClosure);
entry = entry->next[aIndex];
}
}
<node question="У него есть колёса?">
<yes><answer value="наркоман" /></yes>
<no><node question="Он живёт в лесу?">…</node></no>
</node>
функ записатьФайл(xml : XmlПисатель)
xml.записатьЗаголовок
xml.открытьТэг("tree")
дерево.корень.записатьXml(xml)
xml.закрытьТэг("tree")
функ Развилка.записатьXml(xml : XmlПисатель)
xml.открытьТег("node")
xml.атрибут("question", вопрос)
xml.открытьТэг("yes")
да.записатьXml(xml)
xml.закрытьТэг("yes")
xml.открытьТэг("no")
нет.записатьXml(xml)
xml.закрытьТэг("no")
xml.закрытьТэг("node")
функ Ответ.записатьXml(xml : XmlПисатель)
xml.открытьТег("answer")
xml.атрибут("value", результат)
xml.закрытьТэг("answer")
функ считатьУзел(xml : XmlЧитатель) : узел
тэг := xml.считатьТэг
в_зависимости_от (тэг)
если "node":
узел := новый Развилка
узел.вопрос = …
xml.войтиВТэг
xml.затребоватьТэг("yes")
xml.войтиВТэг
узел.да = считатьУзел(xml)
xml.выйтиИзТэга
xml.затребоватьТэг("no")
xml.войтиВТэг
узел.нет = считатьУзел(xml)
xml.выйтиИзТэга
xml.выйтиИзТэга
верни узел
если "answer":
узел := новый Ответ
узел.результат = …
верни узел
иначе:
ошибка
функ Дерево.считатьXml(xml : XmlЧитатель)
xml.затребоватьТэг("tree")
xml.войтиВТэг
узел := считатьУзел(xml)
xml.выйтиИзТэга
установитьКорень(узел)
Q
У него есть колёса?
A
наркоман
Q
Он живёт в лесу?
…
функ записатьXml(xml, узел)
если узел.да≠⌀ и узел.нет≠⌀
ветвь_для развилки
иначе если узел.да=⌀ и узел.нет=⌀
ветвь_для_ответа
иначе ошибка
// Начало Unit1
// Начало Unit2
// Начало Unit3
// Начало Unit1
// Поскольку сработала защита от двойного включения, второго включения не было.
// Так что кода typedef int Type1; к сожалению, йок.
// Конец Unit1
extern Type1 var3; // Type1, естественно, не определён.
// Си (как минимум старые редакции) это понимает как extern int Type1 var3.
// Конец Unit3
// Конец Unit2
// Определение стоит ниже по коду, но это ПЕРВОЕ включение.
typedef int Type1;
// Конец Unit1
function InterlockedAdd(var Addend: Integer; Increment: Integer): Integer;
asm
MOV ECX,EAX
MOV EAX,EDX
LOCK XADD [ECX],EAX
ADD EAX,EDX
end;
mov eax, spinlock_address
mov ebx, SPINLOCK_BUSY
wait_cycle:
xchg [eax], ebx ; xchg - единственная инструкция, являющаяся атомарной без префикса lock
cmp ebx, SPINLOCK_FREE
jnz wait_cycle
; < критическая секция захвачена данным потоком, здесь идёт работа с разделяемым ресурсом >
mov eax, spinlock_address
mov ebx, SPINLOCK_FREE
xchg [eax], ebx ; используется xchg для атомарного изменения
; последние 3 инструкции лучше заменить на mov [spinlock_address], SPINLOCK_FREE -
; это увеличит скорость за счёт отсутствия лишней блокировки шины, а mov и так выполнится атомарно
; (но только если адрес spinlock_address выровнен по границе двойного слова)
1.
char row0[] = { 'A', 'B' };
char row1[] = { 'C', 'D' };
char* arr1[] = { row0, row1 };
char** data1 = arr;
2.
char* arr2[] = { "AB", "CD" };
char** data2 = arr2;
3.
char* errptr;
int r = strtod("10", &errptr);
return (*errptr != '\0') ? ERROR : r;
4.
char* data = "Data";
char** pData = &data;
namespace curl {
std::atomic<size_t> nLib(0);
class _Lib
{
public:
bool isIn = false;
~_Lib();
};
_Lib lib;
void addLib()
{
int q = ++nLib;
if (q == 1) {
lib.isIn = true;
q = ++nLib;
curl_global_init(CURL_GLOBAL_ALL);
}
//std::cout << "Added lib, now " << q << std::endl;
}
void releaseLib()
{
int q = --nLib;
if (q == 0) {
//std::cout << "Cleaned up lib" << std::endl;
curl_global_cleanup();
} else {
//std::cout << "Released lib, now " << q << std::endl;
}
}
_Lib::~_Lib()
{
if (isIn)
releaseLib();
}
}
curl::Curl::Curl()
{
addLib();
fData.handle = curl_easy_init();
}
curl::Curl::~Curl()
{
if (fData.handle)
curl_easy_cleanup(fData.handle);
releaseLib();
}
char *format = (char*)malloc((sizeof(PACKAGE_NAME) + sizeof(PACKAGE_VERSION) + sizeof(msg)) * sizeof(arguments));
char format[200];
будет лучше.static const char* FORMAT1 = "[%s-%s]: %s\n";
char *format = (char*)malloc(strlen(FORMAT1) + strlen(msg) + strlen(PACKAGE_NAME) + strlen(PACKAGE_VERSION) + 1);
sprintf(format, "[%s-%s]: %s\n", PACKAGE_NAME, PACKAGE_VERSION, msg);
va_start(arguments, msg);
vprintf(format, arguments);
va_end(arguments);
free(format);
printf("[%s-%s]: ", PACKAGE_NAME, PACKAGE_VERSION);
va_list arguments;
va_start(arguments, msg);
vprintf(msg, arguments);
va_end(arguments);
putchar('\n');
char *msgbuf = (char*)malloc(strlen(msg) * sizeof(arguments));
int* argkeys::shortName
вы присваиваете строковый литерал, то есть const char*
.int option::val
вы присваиваете argkeys::shortName
то есть int*.if (strcmp(string_1, "0") == 0)
.'\0'
.