Поиск по сайту:

Учебник по программированию на C. Часть 4. Переменные и память


В этой серии руководств мы обсудили, как создать и запустить базовую программу на C, что такое препроцессоры, а также основы работы с переменными. Теперь давайте углубимся в переменные и обсудим аспект памяти.

Предполагая, что вы уже прошли все наши руководства (или у вас есть базовые знания, необходимые для понимания этого руководства), давайте начнем с простого примера кода, который мы использовали в одном из наших предыдущих руководств.

#include <stdio.h>

int main (void)
{
int num = 0, temp=0;
printf("\n Enter a positive integer: ");
scanf("%d", &num);
temp = num;
int result = 1;
while (temp > 0)
{
result = result * temp;
temp = temp -1;
}

printf("\n Factorial of %d is %d\n", num, result);

return 0;
}

Эта программа, как видите, вычисляет факториал числа, введенного пользователем.

Теперь для меньших целых чисел, таких как 5 или 6, эта программа будет работать нормально — она правильно выведет результат факториала. Но, скажем, вы попробуете это для числа 13. Вот результат, который вы получите:

Factorial of 13 is 1932053504

Но это не так, так как факториал числа 13 равен 6227020800. Поэтому, естественно, возникает вопрос, почему наша программа дала неверный ответ? Что ж, ответ заключается в объеме памяти, которую переменная int занимает в системе.

В большинстве современных систем int занимает 4 байта (или 32 бита) памяти. Обратите внимание, что вы можете использовать следующую строку в своей программе, чтобы узнать количество байтов, занимаемых int в вашей системе.

printf("\n int size in bytes is: %d ", sizeof (int));

А поскольку переменная int также может хранить отрицательные значения, диапазон значений, которые она может хранить, варьируется от -2 147 483 648 до 2 147 483 647.

Теперь, поскольку факториал 13 намного больше, чем максимальное значение, которое может содержать переменная int, наша программа выдает неправильный результат. Единственный способ исправить программу — использовать тип переменной, способный хранить 6227020800.

Если вы хотите хранить большее положительное целочисленное значение, вы можете использовать тип unsigned int, который может хранить значения в диапазоне от 0 до 4 294 967 295 (при условии, что переменные этого типа занимают в вашей системе 4 байта). Но здесь даже unsigned int не подойдет, поскольку факториал 13 превышает его максимальную емкость.

Так что нашим спасителем здесь будет long long, занимающий 8 байт или 64 бита памяти. Итак, пересмотренная программа:

#include <stdio.h>

int main (void)
{
long long num = 0; long long temp=0;
printf("\n Enter a positive integer: ");
scanf("%d", &num);
temp = num;
long long result = 1;
while (temp > 0)
{
result = result * temp;
temp = temp -1;
}

printf("\n Factorial of %lld is %lld\n", num, result);

return 0;
}

Чтобы заставить printf или scanf идентифицировать длинную длинную переменную, используйте %lld (или %I64d в некоторых случаях). Вот результат, который производит эта модифицированная программа:

Factorial of 13 is 6227020800 

Что правильно.

Итак, теперь мы знаем ограничения int и то, как можно использовать unsigned int и long long для их преодоления. Имейте в виду, что долго; также является переменным типом, но в большинстве современных систем как int, так и long занимают 4 байта.

О, и да, в то время как int, unsigned int и long long предназначены для целых чисел, есть float и double для чисел с плавающей запятой. Число с плавающей запятой – 32-битное, с точностью до 7 десятичных знаков, а число double – 64-битное, с точностью до 15 знаков после запятой.

Упоминание чисел с плавающей запятой подводит меня к еще одному важному моменту. Это связано с разделением. Давайте возьмем простой пример кода C, чтобы понять это.

int main (void)
{
int a=5, b=10;

printf("\n a/b is %d", a/b);

return 0;
}

Итак, эта программа ничего не делает, а только делит а на b или 5 на 10.

В реальной жизни, если вы спросите кого-нибудь о результате 5/10, вы получите 0,5 в качестве ответа в большинстве случаев. Но здесь ответ будет нулевым (0). Причина в том, что и a, и b являются целыми числами, и, следовательно, результат их деления также будет считаться целым числом, поэтому плавающая часть будет проигнорирована.

Чтобы сохранить плавающую часть, вы должны убедиться, что и a, и b являются переменными с плавающей запятой.

#include <stdio.h>

int main (void)
{
float a=5, b=10;

printf("\n a/b is %f", a/b);

return 0;
}

В этом случае выход будет 0,5.

В этом уроке мы обсудили размер переменных и то, как они влияют на хранение значений. Надеюсь, у вас есть хорошее представление о том, как и когда использовать int, unsigned int, long long, float и double. В следующем уроке мы обсудим переменные символьного типа, а также массивы.