Переменные в Си. Операции
Переменные в си служат для хранения, изменения информации. У каждой переменной в си есть имя и значения. Значения переменной в ходе программы си можно изменять. Чтобы работать с переменными в си, их нужно сначала объявить. Это значит указать их тип и имя.
Примеры объявления переменных в си
int a; // объявлена целочисленная переменная с именем a
float b, c; //объявлены вещественные переменные b и с
char e; // объявлена символьная переменная с именем e
Чтобы работать со строкой символов в си используется объявление массива символов.
char имя строки[длина строки];
Пример объявления строковой переменной в си
char name[50]; //объявлена строка с именем name длиной 50
Чтобы присвоить или изменить значение переменной используется =
Примеры присваивания значений переменных в си
int a,b,c; // объявлены целочисленные переменные a, b, c
a=10; // переменной a присваивается значение 10
b=20; // переменной b присваивается значение 20
c=a+b; // в переменную с присваивается сумма a и b
char c; // объявлена символьная переменная с
c=’V’; // символьной переменной c присваивается символ V
char name[50]; // объявлена строка name
name=”Вася”; // строке присваивается текст Вася
Знаки арифметических действий с числовыми переменными в си
+ — сложение, вычитание
* / умножение, деление
% остаток от деления
Стандартные функции для числовых переменных
abs(i) модуль целого числа i
fabs(x) модуль вещественного числа x
sqrt(x) квадратный корень из вещественного числа x
pow(x,y) вычисляет x в степени y
Вернуться к содержанию
Перейти к следующему уроку Вывод информации на экран в Си.
Как присвоить значение переменной в c
Операции присваивания позволяют присвоить некоторое значения. Эти операции выполняются над двумя операндами, причем левый операнд может представлять только модифицируемое именованное выражение, например, переменную.
Базовая операция присваивания = позволяет присвоить значение правого операнда левому операнду:
int x <>; x = 2;
То есть в данном случае переменная x (левый операнд) будет иметь значение 2 (правый операнд).
Стоит отметить, что тип значения правого операнда не всегда может совпадать с типом левого операнда. В этом случае компилятор пытается преобразовать значение правого операнда к типу левого операнда.
При этом операции присваивания имеют правосторонний порядок, то есть выполняются справа налево. И, таким образом, можно выполнять множественное присваивание:
int a <>, b<>, c<>; a = b = c = 34;
Здесь сначала вычисляется значение выражения c = 34 . Значение правого операнда — 34 присваивается левому операнду с. Далее вычисляется выражение b = c : значение правого операнда c (34) присваивается левому операнду b . И в конце вычисляется выражение a = b : значение правого операнда b (34) присваивается левому операнду a .
Кроме того, следует отметить, что операции присваивания имеют наименьший приоритет по сравнению с другими типами операций, поэтому выполняются в последнюю очередь:
int x <>; x = 3 + 5;
В соответствии с приоритетом операций вначале выполняется выражение 3 + 5 , и только потом его значение присваивается переменной x.
Все остальные операции присваивания являются сочетанием простой операции присваивания с другими операциями и имеют общую форму op= :
- += : присваивание после сложения. Присваивает левому операнду сумму левого и правого операндов: 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
#include int main() < int a ; a += 10; // 15 a -= 3; // 12 a *= 2; // 24 a /= 6; // 4 a >= 2; // 16 std::cout
Как присвоить переменной char значение слова
@avp Вообще-то, это не стандартная функция. Это POSIX функция. Ей можно пользоваться, но чтобы код компилировался, нужно либо задать макрообъявление, либо опцию компилятора.
12 дек 2016 в 21:47
Ну, Вы даете. И с каких это пор POSIX не стандарт? Вообще, если в gnu есть, то можно пользоваться. А если где-то ее (или какой другой) и не будет, значит самому надо там реализовать.
12 дек 2016 в 22:05
@avp POSIX — не указ C стандарту.:)
12 дек 2016 в 22:13
POSIX — не указ C стандарту.:) О Господи. А вот это : «POSIX (англ. portable operating system interface — переносимый интерфейс операционных систем) — набор стандартов, описывающих интерфейсы между операционной системой и прикладной программой (системный API), библиотеку языка C и набор приложений и их интерфейсов. » — ничего не значит? Стандарт, в котором оговариваются БИБЛИОТЕКИ С не указ для БИБЛИОТЕК С ?!
13 дек 2016 в 2:43
- c
- массивы
- указатели
- строковый-литерал
Переменные
Теги: Си переменные. char, int, unsigned, long, long long, float, double, long double, long float, lexical scoping. Объявление переменных. Область видимости. Инициализация переменных. Имена переменных. Экспоненциальная форма.
Переменные
П еременные используются для хранения значений (sic!). Переменная характеризуется типом и именем. Начнём с имени. В си переменная может начинаться с подчерка или буквы, но не с числа. Переменная может включать в себя символы английского алфавита, цифры и знак подчёркивания. Переменная не должна совпадать с ключевыми словами (это специальные слова, которые используются в качестве управляющих конструкций, для определения типов и т.п.)
А также ряд других слов, специфичных для данной версии компилятора, например far, near, tiny, huge, asm, asm_ и пр.
Например, правильные идентификаторы
a, _, _1_, Sarkasm, a_long_variable, aLongVariable, var19, defaultX, char_type
неверные
1a, $value, a-long-value, short
Си — регистрозависимый язык. Переменные с именами a и A, или end и END, или perfectDark и PerfectDarK – это различные переменные.
Типы переменных
- 1) Размер переменной в байтах (сколько байт памяти выделит компьютер для хранения значения)
- 2) Представление переменной в памяти (как в двоичном виде будут расположены биты в выделенной области памяти).
Целые
- char — размер 1 байт. Всегда! Это нужно запомнить.
- short — размер 2 байта
- int — размер 4 байта
- long — размер 4 байта
- long long — размер 8 байт.
Указанные выше значения характерны для компилятора VC2012 на 32-разрядной машине. Так что, если ваша программа зависит от размера переменной, не поленитесь узнать её размер.
Теперь давайте определим максимальное и минимальное число, которое может хранить переменная каждого из типов. Числа могут быть как положительными, так и отрицательными. Отрицательные числа используют один бит для хранения знака. Иногда знак необходим (например, храним счёт в банке, температуру, координату и т.д.), а иногда в нём нет необходимости (вес, размер массива, возраст человека и т.д.). Для этого в си используется модификатор типа signed и unsigned. unsigned char — все 8 бит под число, итого имеем набор чисел от 00000000 до 11111111 в двоичном виде, то есть от 0 до 255 signed char от -128 до 128. В си переменные по умолчанию со знаком. Поэтому запись char и signed char эквивалентны.
| Тип | Размер, байт | Минимальное значение | Максимальное значение |
|---|---|---|---|
| unsigned char | 1 | 0 | 255 |
| signed char ( char ) |
1 | -128 | 127 |
| unsigned short | 2 | 0 | 65535 |
| signed short ( short ) |
2 | -32768 | 32767 |
| unsigned int ( unsigned ) |
4 | 0 | 4294967296 |
| signed int ( int ) |
4 | -2147483648 | 2147483647 |
| unsigned long | 4 | 0 | 4294967296 |
| signed long ( long ) |
4 | -2147483648 | 2147483647 |
| unsigned long long | 8 | 0 | 18446744073709551615 |
| signed long long ( long long ) |
8 | -9223372036854775808 | 9223372036854775807 |
sizeof
В си есть оператор, который позволяет получить размер переменной в байтах. sizeof переменная, или sizeof(переменная) или sizeof(тип). Это именно оператор, потому что функция не имеет возможности получить информацию о размере типов во время выполнения приложения. Напишем небольшую программу чтобы удостовериться в размерах переменных.
#include #include int main() < char c; short s; int i; long l; long long L; //Вызов sizeof как "функции" printf("sizeof(char) = %d\n", sizeof(c)); printf("sizeof(short) = %d\n", sizeof(s)); printf("sizeof(int) = %d\n", sizeof(i)); printf("sizeof(long) = %d\n", sizeof(l)); printf("sizeof(long long) = %d\n", sizeof(L)); //Вызов как оператора printf("sizeof(char) = %d\n", sizeof c); printf("sizeof(short) = %d\n", sizeof s); printf("sizeof(int) = %d\n", sizeof i); printf("sizeof(long) = %d\n", sizeof l); printf("sizeof(long long) = %d\n", sizeof L); _getch(); >
(Я думаю ясно, что переменные могут иметь любое валидное имя). Эту программу можно было написать и проще
#include #include int main() < printf("sizeof(char) = %d\n", sizeof(char)); printf("sizeof(short) = %d\n", sizeof(short)); printf("sizeof(int) = %d\n", sizeof(int)); printf("sizeof(long) = %d\n", sizeof(long)); printf("sizeof(long long) = %d\n", sizeof(long long)); //нельзя произвести вызов sizeof как оператора для имени типа //sizeof int - ошибка компиляции _getch(); >
В си один и тот же тип может иметь несколько названий
short === short int
long === long int
long long === long long int
unsigned int === unsigned
Типы с плавающей точкой
- float — 4 байта,
- long float — 8 байт
- double — 8 байт
- long double — 8 байт.
| Тип | Размер, байт | Количество значащих знаков мантиссы | Минимальное значение | Максимальное значение |
|---|---|---|---|---|
| float | 4 | 6-7 | 1.175494351 E – 38 | 3.402823466 E + 38 |
| double | 8 | 15-16 | 2.2250738585072014 E – 308 | 1.7976931348623158 E + 308 |
Переполнение переменных
Си не следит за переполнением переменных. Это значит, что постоянно увеличивая значение, скажем, переменной типа int в конце концов мы «сбросим значение»
#include #include void main() < unsigned a = 4294967295; int b = 2147483647; //Переполнение беззнакового типа printf("%u\n", a); a += 1; printf("%u", a); //Переполнение знакового типа printf("%d\n", b); b += 1; printf("%d", b); getch(); >
Вообще, поведение при переполнении переменной определено только для типа unsigned: Беззнаковое целое сбросит значение. Для остальных типов может произойти что угодно, и если вам необходимо следить за переполнением, делайте это вручную, проверяя аргументы, либо используйте иные способы, зависящие от компилятора и архитектуры процессора.
Постфиксное обозначение типа
- 11 — число типа int
- 10u — unsigned
- 22l или 22L — long
- 3890ll или 3890LL — long long (а также lL или Ll)
- 80.0f или 80.f или 80.0F — float (обязательно наличие десятичной точки в записи)
- 3.0 — число типа double
#include #include int main()
Следующий код, однако, не будет приводить к ошибкам, потому что происходит неявное преобразование типа
int a = 10u; double g = 3.f;
Шестнадцатеричный и восьмеричный формат
В о время работы с числами можно использовать шестнадцатеричный и восьмеричный формат представления. Числа в шестнадцатиричной системе счисления начинаются с 0x, в восьмеричной системе с нуля. Соответственно, если число начинается с нуля, то в нём не должно быть цифр выше 7:
#include #include void main()
Экспоненциальная форма представления чисел
Э кспоненциальной формой представления числа называют представление числа в виде M e ± p , где M — мантиса числа, p — степень десяти. При этом у мантисы должен быть один ненулевой знак перед десятичной запятой.
Например 1.25 === 1.25e0, 123.5 === 1.235e2, 0.0002341 === 2.341e-4 и т.д.
Представления 3.2435e7 эквивалентно 3.2435e+7
Существеут и другое представление («инженерное»), в котором степень должна быть кратной тройке. Например 1.25 === 1.25e0, 123.5 === 123.5e0, 0.0002341 === 234.1e-6, 0.25873256 === 258.73256e-3 и т.д.
Объявление переменных
В си переменные объявляются всегда в начале блока (блок — участок кода ,ограниченный фигурными скобками)
При объявлении переменной пишется её тип и имя.
int a; double parameter;
Можно объявить несколько переменных одного типа, разделив имена запятой
long long arg1, arg2, arg3;
#include #include int main() < int a = 10; int b; while (a>0) < int z = a*a; b += z; >>
Здесь объявлены переменные a и b внутри функции main, и переменная z внутри тела цикла. Следующий код вызовет ошибку компиляции
int main()
Это связано с тем, что объявление переменной стоит после оператора присваивания. При объявлении переменных можно их сразу инициализировать.
int i = 0;
При этом инициализация при объявлении переменной не считается за отдельный оператор, поэтому следующий код будет работать
int main()
Начальное значение переменной
О чень важно запомнить, что переменные в си не инициализируются по умолчанию нулями, как во многих других языках программирования. После объявления переменной в ней хранится «мусор» — случайное значение, которое осталось в той области памяти, которая была выделена под переменную. Это связано, в первую очередь, с оптимизацией работы программы: если нет необходимости в инициализации, то незачем тратить ресурсы для записи нулей (замечание: глобальные переменные инициализируются нулями, почему так, читайте в этой статье).
#include #include int main()
Если выполнять эту программу на VC, то во время выполнения вылетит предупреждение
Run-Time Check Failure #3 — The variable ‘i’ is being used without being initialized.
Если нажать «Продолжить», то программа выведет «мусор». В многих других компиляторах при выполнении программы не будет предупреждения.
Область видимости переменной
П еременные бывают локальными (объявленными внутри какой-нибудь функции) и глобальными. Глобальная переменная видна всем функциям, объявленным в данном файле. Локальная переменная ограничена своей областью видимости. Когда я говорю, что переменная «видна в каком-то месте», это означает, что в этом месте она определена и её можно использовать. Например, рассмотрим программу, в которой есть глобальная переменная
#include #include int global = 100; void foo() < printf("foo: %d\n", global); >void bar(int global) < printf("bar: %d\n", global); >int main()
Будет выведено
foo: 100
bar: 333
Здесь глобальная переменная global видна всем функциям. Но аргумент функции затирает глобальную переменную, поэтому при передаче аргумента 333 выводится локальное значение 333.
Вот другой пример
#include #include int global = 100; int main()
Программа выведет 555. Также, как и в прошлом случае, локальная переменная «важнее». Переменная, объявленная в некоторой области видимости не видна вне её, например
#include #include int global = 100; int main() < int x = 10; < int y = 30; printf("%d", x); >printf("%d", y); >
Этот пример не скомпилируется, потому что переменная y существует только внутри своего блока.
Вот ещё пример, когда переменные, объявленные внутри блока перекрывают друг друга
#include #include int global = 100; int main() < int x = 10; < int x = 20; < int x = 30; printf("%d\n", x); >printf("%d\n", x); > printf("%d\n", x); getch(); >
Программа выведет
30
20
10
Глобальных переменных необходимо избегать. Очень часто можно услышать такое. Давайте попытаемся разобраться, почему. В ваших простых проектах глобальные переменные выглядят вполне нормально. Но представьте, что у вас приложение, которое
- 1) Разрабатывается несколькими людьми и состоит из сотен тысяч строк кода
- 2) Работает в несколько потоков
Во-первых, глобальная переменная, если она видна всем, может быть изменена любой частью программы. Вы изменили глобальную переменную, хотите её записать, а другая часть программы уже перезаписала в неё другое значение (на самом деле это целый класс проблем, которые возникают в многопоточной среде). Во-вторых, при больших размерах проекта не уследить, кто и когда насоздавал глобальных переменных. В приведённых выше примерах видно, как переменные могут перекрывать друг друга, то же произойдёт и в крупном проекте.
Безусловно, есть ситуации, когда глобальные переменные упрощают программу, но такие ситуации случаются не часто и не в ваших домашних заданиях, так что НЕ СОЗДАВАЙТЕ ГЛОБАЛЬНЫХ ПЕРЕМЕННЫХ!
Переменные могут быть не только целочисленными и с плавающей точкой. Существует множество других типов, которые мы будем изучать в дальнейшем.
ru-Cyrl 18- tutorial Sypachev S.S. 1989-04-14 sypachev_s_s@mail.ru Stepan Sypachev students

Всё ещё не понятно? – пиши вопросы на ящик