Finished 4.4 paragraph

This commit is contained in:
t0xa 2026-02-09 23:19:28 +03:00
parent 825ff0b524
commit 12d4f8d626
4 changed files with 119 additions and 0 deletions

View file

@ -0,0 +1,8 @@
{
"permissions": {
"allow": [
"Bash(echo:*)",
"Bash(nvim:*)"
]
}
}

View file

@ -0,0 +1,40 @@
# Глоссарий
- `Automatic variables` - локальные перменные функции, которые создаются только во время, когда вызвана функция, и исчезают, когда функция остановлена (exited);
- `Scope of a name` - часть программы, в рамках которой имя может быть использовано;
***
# Глава 4.3 - Внешние переменные
| 2026-02-09 22:56 |
Какая-то атомная дрочь с калькулятором и витиеватым описанием примера с `getch` и `ungetch`.
Пока пример опустил, суть то ясна о том, как работают области видимости
# Глава 4.4 - Области видимости
`Scope of external variable/function` - длится от точки, где он объявлен и до конца файла, который будет скомпилирован.
Например:
```c
main() { ... }
int sp = 0;
double val[MAXVAL];
void push(double f) { ... }
double pop(void) { ... }
```
Тут:
- `sp`, `val` могут быть использованы в `push` и `pop`
- `sp`, `val`, `push`, `pop` не видимы для функции `main`
## extern
Если на внешнюю переменную нужно сослаться до ее определения, или же она определена в другом исходном файле, который отличается от того, где ее пытаются вызвать - необходимо использовать слово `extern`.
Важно различать *decalaration* и *definintion* внешней переменной.
- decalaration: объявляет пропертисы переменной (тип);
- definintion: так-же выделяет память под нее.
*Например*
```c
int sp;
double val[MAXVAL];
```
Если они объявлены вне функций, то они определяют (**define**) внешние переменные, выделяя под них память и также выступая декларацией для остального исходного файла
```c
extern int sp;
extern double val[];
```
Декларируют (**declare**) что `sp` это `int`, а `val` - массив `double` (размер которого определен в другом месте), но они не создают эти переменные и не резервируют память под них.

View file

@ -1,12 +1,79 @@
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#define MAXOP 100 // Максимальный размер операдна (цифры) или оператора
#define MAXVAL 100 // Максимальный размер стека (глубина)
#define NUMBER '0' // Признак числа
#define BUFSIZE 100
int getop(char[]);
void push(double);
double pop(void);
int getch(void);
void ungetch(int);
int sp = 0; /* Следующая свободная позиция в стеке */
int bufp = 0; /* след, свободная позиция в буфере */
double val[MAXVAL]; /* stack */
char buf[BUFSIZE]; /* буфер для ungetch */
int getch(void) /* взять (возможно возвращенный) символ */
{
return (bufp > 0) ? buf[--bufp] : getchar();
}
void ungetch(int с) /* вернуть символ на ввод */
{
if (bufp >= BUFSIZE)
printf("ungetch: слишком много символов\n");
else
buf[bufp++] = с;
}
void push(double f) {
if (sp < MAXVAL) {
val[++sp] = f;
}
else {
printf("Stack maximum depth reached: %c", MAXVAL);
}
}
double pop(void) {
if (sp > 0) {
return val[--sp];
} else {
printf("Stack is empty. Returning 0.0");
return 0.0;
}
}
/**
* @brief Функция получения следующего оператора или операнда
*
* @param s массив символов для оценки
*/
int getop(char s[]) {
int i, c;
while ((s[0] = c = getch()) == ' ' || c == '\t')
;
s[1] = '\0';
if (!isdigit(c) && c != '.')
return c;
i = 0;
/* Накапливаем целую часть */
if (isdigit(c))
while (isdigit(s[++i] = c = getch()))
;
/* Накапливаем дробную часть */
if (c == '.')
while (isdigit(s[++i] = c = getch()))
s[i] = '\0';
if (c != EOF)
ungetch(c);
return NUMBER;
}
int main() {
int type;

View file

@ -0,0 +1,4 @@
int main() {
return 0;
}
int sp = 0;