184 lines
14 KiB
Markdown
184 lines
14 KiB
Markdown
|
---
|
|||
|
title: More math
|
|||
|
localeTitle: Больше математики
|
|||
|
---
|
|||
|
# Больше математики в C
|
|||
|
|
|||
|
Хорошо, так что вы видели основы. Там намного больше на C, так что вот посмотрите на это.
|
|||
|
|
|||
|
## Порядок операций
|
|||
|
|
|||
|
Взгляните на следующее уравнение:
|
|||
|
|
|||
|
> 1 + (3-2) \* 5
|
|||
|
|
|||
|
Если бы мы просто прочитали и вычислили слева направо, мы бы взяли 1, добавим 3, вычтем 2 и умножим на 5, получив 10. Однако это не учитывает порядок операций. Сначала мы должны сделать (3-2), получив 1, затем умножим на 5, затем добавим 1. Это дает ответ 6.
|
|||
|
|
|||
|
Как и в обычной математике, C имеет порядок операций. Операции имеют приоритет, и если одна операция имеет более высокий приоритет, чем другой, более высокий приоритет будет вычисляться первым. Использование скобок может увеличить приоритет, как и в обычной математике.
|
|||
|
|
|||
|
## Унарные операции
|
|||
|
|
|||
|
Унарные операции - это операции, в которых имеется только одна переменная. Есть несколько в C.
|
|||
|
|
|||
|
### Операторы после исправления и предварительной фиксации
|
|||
|
|
|||
|
Есть много ситуаций, когда вы хотите взять номер и либо перейти вверх, либо вниз на 1. В этих ситуациях у нас есть пост-исправить и предварительно исправить операторы:
|
|||
|
|
|||
|
```C
|
|||
|
1: a++;
|
|||
|
2: ++a;
|
|||
|
|
|||
|
3: a--;
|
|||
|
4: --a;
|
|||
|
```
|
|||
|
|
|||
|
Оба примера в 1 и 2 увеличивают значение a на единицу. Оба примера в 3 и 4 уменьшат значение a на единицу. Однако 1 не делает то же самое, что и 2, а 3 не делает то же самое, что и 4. Операции pre-fix называются так, потому что операция является префиксом (2 и 4 являются нашими префиксными операторами). Это действует несколько иначе, чем наши операторы после исправления в 1 и 3. Операторы pre-fix выполняют операцию, а затем возвращают значение. Операторы post-fix возвращают значение, а затем выполняют инкремент.
|
|||
|
|
|||
|
### Унарный плюс и минус
|
|||
|
|
|||
|
В обычной математике, к которой вы привыкли, вы используете «-» перед числом или переменной, что делает число или переменную отрицательной. Если число или переменная уже отрицательное, оно становится положительным.
|
|||
|
|
|||
|
C делает то же самое: поставить `-` перед номером или переменной , чтобы иметь такой эффект, как так:
|
|||
|
|
|||
|
```C
|
|||
|
int number = -3;
|
|||
|
number = -number;
|
|||
|
```
|
|||
|
|
|||
|
Таким образом, `number` начинается как отрицательное 3, но затем становится положительным, потому что отрицательный отрицательный положительный.
|
|||
|
|
|||
|
## Побитовые операции
|
|||
|
|
|||
|
Поскольку C - низкий уровень, как упоминалось ранее, у вас есть доступ к отдельным бинарным битам (если вы решите воспользоваться этим). Есть встроенные двоичные операции, позволяющие нам это делать. Для этих примеров мы будем использовать `a` и `b` как наши переменные. Они могут быть любой переменной, потому что все переменные будут представлены в битах, поэтому для них точный тип данных не имеет значения.
|
|||
|
|
|||
|
### А ТАКЖЕ
|
|||
|
|
|||
|
`c = a & b;` будет выполнять побитовое И. Это означает, что если первый бит `a` и первый бит `b` равны 1, первый бит c будет равен 1 и 0 в противном случае. Если второй бит `a` и `b` равен 1, второй бит c будет равен 1 и 0 в противном случае. Это продолжается до тех пор, пока все биты не будут и не будут.
|
|||
|
|
|||
|
### ИЛИ
|
|||
|
|
|||
|
`c = a | b;` будет выполнять побитовое ИЛИ. Первый бит `c` равен 1, если первый бит в `a` или `b` равен 1, второй бит равен 1, если второй бит в `a` или `b` равен 1 и так далее.
|
|||
|
|
|||
|
### НЕ
|
|||
|
|
|||
|
`b = ~a;` будет устанавливать `b` в дополнение к `a` , означая, что любое 1 становится 0, а любое 0 становится 1.
|
|||
|
|
|||
|
### XOR
|
|||
|
|
|||
|
`c = a ^ b;` будет выполнять побитовое XOR. Это является исключительным или, что означает, что первый бит `c` равен 1, если `a` или `b` равно 1, но не оба. Второй бит равен 1, если либо 1, но не оба, и так далее.
|
|||
|
|
|||
|
### сдвиг
|
|||
|
|
|||
|
Поразрядный сдвиг будет принимать бит и перемещать их в некоторое количество мест влево или вправо. Например, скажем, у нас есть набор бит: `101110` . C выполняет арифметический сдвиг при смещении бит. Давайте используем таблицу, чтобы сделать это более понятным:
|
|||
|
|
|||
|
| Бит | | 1 | 2 | 3 | 4 | 5 | 6 | | ------- | --- | --- | --- | --- | --- | --- | --- | | До | | 1 | 0 | 1 | 1 | 1 | 0 | | Во время | 1 | 0 | 1 | 1 | 1 | 0 | | | После | | 0 | 1 | 1 | 1 | 0 | 0 |
|
|||
|
|
|||
|
Это арифметический побитовый сдвиг, идущий один влево. Обратите внимание, что в сдвиге влево левый 1, который начинался в позиции 1, оказался вне пространства, которое он мог поместить, поэтому он был удален. В смену слева появилось отверстие, и оно было заполнено 0.
|
|||
|
|
|||
|
Теперь давайте посмотрим на арифметическую битрейт справа:
|
|||
|
|
|||
|
| Бит | 1 | 2 | 3 | 4 | 5 | 6 | | | ------- | --- | --- | --- | --- | --- | --- | --- | | До | 1 | 0 | 1 | 1 | 1 | 0 | | | Во время | | 1 | 0 | 1 | 1 | 1 | 0 | | После | 1 | 1 | 0 | 1 | 1 | 1 | |
|
|||
|
|
|||
|
Обратите внимание, что здесь слот открывается в позиции 1, но вместо заполнения 0 он заполняется самым значительным битом. В этом случае это 1. Если бит, который начался в позиции 1, равен 0, пробелы были бы заполнены 0.
|
|||
|
|
|||
|
Это связано с тем, что числа на вашем компьютере представлены с использованием двух дополнений, поэтому смещение таким образом не делает отрицательное число положительным. Two Complement заслуживает большего внимания, если вы заинтересованы в том, как компьютеры используют двоичный код для выполнения математики и представления чисел.
|
|||
|
|
|||
|
Чтобы выполнить сдвиг влево, используйте оператор `<<` так:
|
|||
|
|
|||
|
```C
|
|||
|
c = a << b;
|
|||
|
```
|
|||
|
|
|||
|
Это сдвинет `a` влево на `b` бит и установит этот результат равным `c` .
|
|||
|
|
|||
|
Этот пример сдвинет `a` вправо на `b` бит и установит этот результат равным `c` .
|
|||
|
|
|||
|
```C
|
|||
|
c = a >> c;
|
|||
|
```
|
|||
|
|
|||
|
## Операторы контировки
|
|||
|
|
|||
|
Иногда вы хотите увеличить переменную на определенное значение. Вы можете сделать это:
|
|||
|
|
|||
|
```C
|
|||
|
a = a + b;
|
|||
|
```
|
|||
|
|
|||
|
Однако это то, для чего предназначены составные операторы присваивания. Вместо этого вы можете написать это, что делает то же самое:
|
|||
|
|
|||
|
```C
|
|||
|
a += b;
|
|||
|
```
|
|||
|
|
|||
|
Это также существует для группы других операторов. Вот вам удобная таблица:
|
|||
|
|
|||
|
Короткие пути | Длинный путь : --------------: |: ------------: `a += b` | `a = a + b` `a -= b` | `a = a - b` `a *= b` | `a = a * b` `a /= b` | `a = a / b` `a %= b` | `a = a % b` `a &= b` | `a = a & b` `a ^= b` | `a = a ^ b` `a <<= b` | `a = a << b` `a >>= b` | `a = a >> b`
|
|||
|
|
|||
|
Там также `|=` , что не на столе, потому что `|` символ разбивает таблицу. Однако он действует как все эти другие операции.
|
|||
|
|
|||
|
## Кастинг
|
|||
|
|
|||
|
Иногда вы не хотите, чтобы число было числом, или вы хотите, чтобы целое число было float или что-то в этом роде. Для этого и подходит кастинг.
|
|||
|
|
|||
|
Как вы помните из обсуждения целочисленного деления, следующий пример даст целочисленное значение без какого-либо десятичного числа, поскольку оба числа, входящие в число, являются целыми числами:
|
|||
|
|
|||
|
```C
|
|||
|
#include <stdio.h>
|
|||
|
|
|||
|
int main(void) {
|
|||
|
int a = 12;
|
|||
|
int b = 5;
|
|||
|
|
|||
|
printf("a divided by b is %i", a/b);
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
Однако, используя литье, мы можем превратить их в поплавки с использованием литья. Это позволяет их разделить как float, и уравнение вернет значение float:
|
|||
|
|
|||
|
```C
|
|||
|
#include <stdio.h>
|
|||
|
|
|||
|
int main(void) {
|
|||
|
int a = 12;
|
|||
|
int b = 5;
|
|||
|
|
|||
|
printf("a divided by b is %f", (float) a / b);
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
Теперь это плавающая точка 12, деленная на 5, так что это возвращает число с плавающей запятой, которое не усекает после десятичной точки.
|
|||
|
|
|||
|
Чтобы превратить число в `int` , используйте `(int)` , чтобы превратить его в `double` , use `(double)` и так далее.
|
|||
|
|
|||
|
## math.h
|
|||
|
|
|||
|
Таким образом, это все встроенный материал, но так же, как вы можете `#include` stdio и stdbool, вы можете включить библиотеку с именем `math.h` Эта библиотека имеет всевозможные полезные функции для всех видов математики. Это стоит прочитать на [странице Википедии,](https://en.wikipedia.org/wiki/C_mathematical_functions#Overview_of_functions) если вы хотите получить полный список функций. Вот пример того, как использовать `abs` , который является первым в своем списке:
|
|||
|
|
|||
|
```C
|
|||
|
a = abs(-1);
|
|||
|
```
|
|||
|
|
|||
|
`abs` вычисляет абсолютное значение переданного ему значения. В этом случае он получает -1, поэтому он превратится в 1, а `a` будет равен 1. Есть еще много возможностей, чтобы дать гораздо больше функциональности, и именно так вы сможете делать экспоненты, тригонометрию, и многое другое.
|
|||
|
|
|||
|
# Прежде чем продолжить ...
|
|||
|
|
|||
|
## Обзор
|
|||
|
|
|||
|
* В C есть еще несколько математических операторов
|
|||
|
* Порядок операций существует в C
|
|||
|
* Скобки существуют и работают так же, как обычная математика, чтобы изменить порядок операций
|
|||
|
* Существует несколько Унарных операций, которые являются операциями, в которых имеется только одна переменная:
|
|||
|
* Операторы post-fix и pre-fix используются для добавления и вычитания 1
|
|||
|
* Добавление одного: `++a;` или `a++;`
|
|||
|
* Вычитая один: `--a` или 'a--'
|
|||
|
* `-` может быть помещена перед переменной или числом и действует так же, как отрицание в математике
|
|||
|
* Есть и побитовые операции
|
|||
|
* И выполняется с &
|
|||
|
* ИЛИ выполняется с |
|
|||
|
* НЕ выполняется с ~
|
|||
|
* XOR выполняется с помощью ^ (XOR не работает с числом плавающего типа в C)
|
|||
|
* Существуют сложные операции присвоения для всех не унарных операций
|
|||
|
* a + = b совпадает с a = a + b и т. д.
|
|||
|
* Кастинг позволяет вам переключаться между типами данных
|
|||
|
* У math.h есть больше математического материала для игры с
|