diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..fc17a95 --- /dev/null +++ b/.clang-format @@ -0,0 +1,7 @@ +--- +Language: Cpp +BasedOnStyle: LLVM +IndentWidth: 2 +UseTab: Never +BreakBeforeBraces: Allman +AllowShortFunctionsOnASingleLine: None diff --git a/.clangd b/.clangd new file mode 100644 index 0000000..ef4a4f8 --- /dev/null +++ b/.clangd @@ -0,0 +1,19 @@ +CompileFlags: + Add: + - -std=c90 + - -Wall + - -Wextra + - -I/home/t0xa/Programming/clang/c_book + - -I/home/t0xa/Programming/clang/c_book/exercices/pointers + - -I/home/t0xa/Programming/clang/c_book/exercices/functions +--- +If: + PathMatch: .*\.h +CompileFlags: + Remove: + - -x + - -std=* + Add: + - -x + - c-header + - -std=c90 diff --git a/exercices/pointers/4_3_getch.c b/exercices/pointers/4_3_getch.c new file mode 100644 index 0000000..e03efb0 --- /dev/null +++ b/exercices/pointers/4_3_getch.c @@ -0,0 +1,15 @@ +#include +#include "4_3_getch.h" +#define BUFSIZE 100 + +char buf[BUFSIZE]; +int bufp = 0; + +int getch(void) { return (bufp > 0) ? buf[--bufp] : getchar(); } + +void ungetch(int c) { + if (bufp >= BUFSIZE) + printf("ungetch: too many charachters\n"); + else + buf[bufp++] = c; +} diff --git a/exercices/pointers/4_3_getch.h b/exercices/pointers/4_3_getch.h new file mode 100644 index 0000000..7568616 --- /dev/null +++ b/exercices/pointers/4_3_getch.h @@ -0,0 +1,4 @@ +#define BUFSIZE 100 + +int getch(void); +void ungetch(int c); diff --git a/exercices/pointers/5_1.c b/exercices/pointers/5_1.c new file mode 100644 index 0000000..a1ee504 --- /dev/null +++ b/exercices/pointers/5_1.c @@ -0,0 +1,8 @@ +#include +int main() { + int x = 1, y = 2, z[10]; + int *ip; /* ip - указатель типа int */ + ip = &x; /* ip теперь указывает на x */ + y = *ip; /* y теперь равно 1 (т.е. *ip dereference'ит x через указатель и присваивает y) */ + *ip = 0; /* x теперь равно 0 через указатель */ +} diff --git a/exercices/pointers/5_1_1.c b/exercices/pointers/5_1_1.c new file mode 100644 index 0000000..5df24e1 --- /dev/null +++ b/exercices/pointers/5_1_1.c @@ -0,0 +1,14 @@ +#include +int main() { + int x = 1, y; + int *ip = &x; + *ip = *ip + 10; /* Добавляем 10 к разименованному указателю */ + y = *ip + 20; /* Добавляем уже к x+10 еще 20 и присваиваем y */ + printf("x: %d, y: %d\n", x, y); + *ip += 1; /* Добавляем 1 к х */ + printf("x: %d\n", x); + ++*ip; + printf("x: %d\n", x); + (*ip)++; + printf("x: %d\n", x); +} diff --git a/exercices/pointers/5_2_function_args.c b/exercices/pointers/5_2_function_args.c new file mode 100644 index 0000000..70546a9 --- /dev/null +++ b/exercices/pointers/5_2_function_args.c @@ -0,0 +1,18 @@ +#include +void swap(int *px, int *py) { + int temp; + + temp = *py; + *px = *py; + *px = temp; +} + +int main() { + int x,y; + x = 10; + y = 20; + printf("x=%d, y=%d", x, y); + swap(&x, &y); + printf("After swap:"); + printf("x=%d, y=%d", x, y); +} diff --git a/exercices/pointers/5_2_getint.c b/exercices/pointers/5_2_getint.c new file mode 100644 index 0000000..2c6ca5b --- /dev/null +++ b/exercices/pointers/5_2_getint.c @@ -0,0 +1,63 @@ +#include "4_3_getch.h" +#include +#include +#include + +/** + * @brief Функция чтения первого токена-числа из ввода stdin + * + * @param pn - указатель на int, в который требуется записать считанное число + * @return последний считанный символ `c` + */ +int getint(int *pn) +{ + int c; /* Это последний считанный символ в процессе работы функции */ + int sign; /* Тут хранится 1 или -1 в зависимости от того, какой sing пришел у + числа */ + + /* Пока у нас приходят пробелы - берем следующий символ через getch()) */ + while (isspace(c = getch())) + ; + + if (!isdigit(c) && c != EOF && c != '+' && c != '-') + { + /* В случае, если пришло не число и не знак - пихаем его в буфер. + * Пихаем мы в буфер со следующей целью - допустим у нас ситуация: + * На вход пришло " x123", тогда получается что на вход пришло не число. + * Т.е. getch() уже прочитал "х", то нам его надо как-то вернуть обратно для + * следующих парсеров. Следовательно перед тем, как выйти с кодом 0 (что + * означает что пришло не число) - мы записываем в буфер значение "х". + * Следующий парсер который начнет это читать - начент чтение с "х" из + * буфера.*/ + ungetch(c); + return 0; + } + + sign = (c == '-') ? -1 : 1; + if (c == '+' || c == '-') + c = getch(); + /* + * Пример парсинга "158": + * старт: *pn = 0 + * '1' -> *pn = 10*0 + 1 = 1 + * '5' -> *pn = 10*1 + 5 = 15 + * '8' -> *pn = 10*15 + 8 = 158 + * + * Почему (c - '0'): + * '0'..'9' идут подряд в ASCII, поэтому разница кодов дает цифру: + * '0' - '0' = 0, '5' - '0' = 5, '9' - '0' = 9 + */ + for (*pn = 0; isdigit(c); c = getch()) + *pn = 10 * *pn + (c - '0'); + *pn *= sign; + if (c != EOF) + ungetch(c); + return c; +} + +int main() +{ + int getint_result; + getint(&getint_result); + printf("Scanned int: %d\n", getint_result); +} diff --git a/exercices/pointers/generic_pointers.c b/exercices/pointers/generic_pointers.c new file mode 100644 index 0000000..88150e9 --- /dev/null +++ b/exercices/pointers/generic_pointers.c @@ -0,0 +1,12 @@ +#include +int main() { + int x = 10; + double y = 3.14; + char c = 'a'; + + void *ptr; + ptr = &x; + printf("%d\n", *(int *)ptr); + ptr = &y; + printf("%.2f\n", *(double *)ptr); +}