Сделай Сам Свою Работу на 5

Переполнение регистров переменных





Пространство имен.

Пример.

 

#include <iostream>

int main( )

{

std ::cout << "Hello World! \n";

return 0;

}

 

Построчно рассмотрим назначение инструкций программы.

 

#include <iostream>

· Подключение к файлу программы внешней библиотеки iostream.

При каждом запуске компилятора запускается препроцессор, он «читает» исходный текст программы, находит строки, начинающиеся с символа #и обрабатывает их перед началом компиляции программы.Файл iostream(Input-Output-Stream – поток вода/вывода[1]) используется объектом cout, который обслуживает процесс вывода данных на экран.

Каждый поток (за исключением строковых) ассоциируется как взаимодействие операционной системы с определенным внешним устройством.

Команда include(подключить) – также инструкция препроцессора, которая указывает, что далее следует имя файла, который необходимо найти и подключить. Угловые скобки, в которые заключается имя подключаемого файла, означают, что файл нужно искать во всех папках, отведенных для хранения подобных файлов.

 

int main( )

· Вызов функции main( ).

Основной код программы начинается с вызова функции main(), ее содержит каждая программа на языке С++. Функция main() имеет тип int, что значит, а это означает, что по окончании работы функция возвратит операционной системе целое число. В данном случае будет возвращено число «0» (инструкция return 0). Возвращение значения в ОС не столь важно и самой системой почти не используется, указанная строка – всего лишь требование стандарта языка С++ к корректному объявлению функции main( ).



Все функции начинаются открывающей «{» и заканчиваются закрывающей «}» фигурной скобкой, между ними располагается тело функции.

 

std ::cout << "Hello World! \n";

· Инструкция вывода на экран строки символов.

Каждый оператор в С++ должен заканчиваться точкой с запятой, «;» иначе называется признаком конца оператора.

Объект coutиспользуется для вывода сообщений либо данных на консоль (экран) – Console Output. Этот объект содержится в стандартной библиотеке. Для указания же компилятору, что будет использован объект именно из нее, используется спецификация пространства имен std.

Пространство имен (namespace) – это некая объявляемая область, необходимая для того, чтобы избежать конфликта имен идентификаторов, объектов. Существует вероятность приобрести аналогичные объекты с тем же именем от другого поставщика программных компонентов, и чтобы компилятор «понял», частью какого пространства является используемый объект, перед словом cout помещается спецификация std в сопровождении двух двоеточий:



std :: cout.

За словом cout следует оператор перенаправления потока вывода ( символ << [2]), все, что следует за этим оператором (правый операнд) выводится на экран. Например, следующая инструкция выводит на экран компьютера число, хранящееся в переменной с:

cout << c ;

Два заключительных символа строки – управляющие символы «\n», означают, что после строки текста необходимо выполнить переход на новую строку (обратный слэш «\» называется знаком перехода), т.е. все, что следует после символов «\n», будет показано с новой строки, сами символы на экран не выводятся.

 

Рассмотрим следующий фрагмент программного кода:

int a=5;

int b=16;

int c=a+b;

std::cout<< "There is variable c: "<<c<<"\n";

В последней строке объекту cout передаются три значения, и каждое отделяется оператором вывода: строка символов "There is variable c: "; значение переменной с; символы новой строки \n. Поскольку после первого значения нет символа начала новой строки, следующее значение выводится вслед за предыдущим:

 

There is variable c: 21_

 

К управляющим символам относятся так же:

 

§ оператор endl (сокращение от end line – конец строки),действие аналогично символу \n. Так можно записать тело функции main( ):

{

std::cout<< "Hello!";



std::cout<< std::endl;

std::cout<<3+6<< std::endl;

}

 

Результат работы программы:

Hello!

Press any key to continue_

 

Типы данных в С++. Определение переменных. Особенности использования некоторых типов данных, переполнение регистров переменных.

Переменная – место в оперативной памяти компьютера (RAM – Random Access Memory), где можно размещать хранимое значение, а затем извлекать его для дальнейшего использования. Значение сохраняется в переменной до выключения компьютера.

Определяя переменную в С++, необходимо предоставить компилятору информацию о ее типе. Тогда компилятор будет знать, сколько место (какой объем оперативной памяти) нужно зарезервировать для хранения переменной, и какого рода значения будут в ней храниться.

В оперативной памяти любой тип занимает определенный объем, но у различных типов компьютеров он может оказаться разным. Тип integer (целое число) может иметь размер в два байта на одной машине и четыре на другой, но в пределах одного компьютера он будет одним и тем же. Размер целого числа определяется системой компьютера (16- или 32-разрядная) и используется компилятором.

Задача определения размеров переменных различных типов на конкретном компьютере может быть решена с использованием функции sizeof( ).Функция поддерживается каждым компилятором, и возвращает размер объекта, переданного ей в качестве параметра. Например запись вида sizeof(int)позволит получить размер переменной типа int.

Таблица 1

Тип данных Размер в байтах Диапазон
char   -128 - 127 (256 значений символов)
unsigned char   0 - 255
bool   true или false
unsigned short int (unsigned short) 0 - 65 535
short int (short)   -32 768 - 32 767
unsigned long int (unsigned long) 0 - 4 294 967 295
long int (long)   -2 147 483 648 - 2 147 483 647
unsigned int (unsigned) 2 или 4 (16/32 байта) 0 - 65 535 или 0 - 4 294 967 295
int 2 или 4 (16/32 байта) -32 768 - 32 767 или -2 147 483 648 - 2 147 483 647
float   1, 2е-38 - 3,4е38
double   2, 2е-308 - 1,8е308

Представление целых чисел

Все целочисленные типы существуют в двух вариантах: signed (знаковые – положительные и отрицательные) и unsigned (беззнаковые - положительные). Такое деление связано с тем, что отрицательные числа иногда нужны, а иногда нет.

 

Данные, имя типа которых включает модификатор signed, являются данными со знаком, имя типа которых содержит модификатор unsigned – данными без знака. При отсутствии модификатора по умолчанию принимается модификатор signed.

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

Например, переменные типа unsigned short int, как правило, имеют размер, равный двум байтам, и могут хранить значение, не превышающее 65 535. Диапазон же типа signed short int (short) поделен между положительными и отрицательными числами, поэтому их максимальное значение вдвое меньше, чем у беззнаковых (от -32 768 до 32 767).

 

Определение переменных

 

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

Тип ИмяПеременной;

 

Допустимо создание нескольких переменных с помощью одного оператора, указав их тип и перечень имен переменных, разделенных запятыми:

Тип ИмяПеременной_1, ИмяПеременной_2, …, ИмяПеременной_n;

Для присвоения значений переменным используется следующая запись:

Тип ИмяПеременной;

ИмяПеременной = значение;

 

Эти две строки можно объединить в одну и инициализировать переменную в процессе ее определения:

Тип ИмяПеременной = значение;

 

Инициализация переменных напоминает присвоение. Существенное отличие инициализации от присвоения состоит в том, что первая происходит в момент создания переменной. Подобно тому, как можно определять сразу несколько переменных, можно и инициализировать сразу несколько переменных. Например:

// создаем две переменных типа long и инициализируем их

long а = 5, b = 7;

Здесь переменная а типа long int инициализируется значением 5, а переменная b того же типа – значением 7. Можно комбинировать определение и инициализацию:

int a = 42, b, c = 41;

Созданы три переменные, а инициализированы две – первая и третья.

 

Особенности использования некоторых типов данных:

переполнение регистров переменных

 

Переменные имеют максимально допустимое значение. Что произойдет при превышении этого предела? Когда беззнаковое целое достигает своего максимального значения, то при очередном добавлении оно сбрасывается в ноль и отсчет начинается сначала.

Пример. Поместим слишком большое число в переменную типа unsigned short.

#include <iostream>

int main( )

{

using std::cout;

using std::endl;

unsigned short int smallNumb;

smallNumb=65535; // максимально 65 535

cout<<"Значение smallNumb:"<<smallNumb<<endl;

//значение переменной должно стать 65 536

smallNumb++;

//переменная сбрасывается в 0

cout<<" Значение smallNumb:"<<smallNumb<<endl;

//переманная увеличивается на 1 но уже с 0

smallNumb++;

cout<<" Значение smallNumb:"<<smallNumb<<endl;

return 0;

}

 

Результат:

Значение smallNumb: 65 535

Значение smallNumb:0

Значение smallNumb:1

Половина диапазона значений знаковых переменных отрицательные числа. Для понимания представления этого типа данных уместна аналогия циферблата, на котором числа увеличиваются при движении от полудня по часовой стрелке и уменьшаются при движении против. Один час от полудни является либо 1 (по часовой стрелке), либо -1 (против). Когда положительные числа будут исчерпаны, начнутся самые большие отрицательные.

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

Пример. Добавим единицу к максимально возможному числу, хранящемуся в переменной типа short int:

#include <iostream>

int main() {

using std::cout;

using std::endl;

short int Numb;

Numb=32767; // диапазон -32 768 до 32 767

cout<<"Значение Numb:"<<Numb<<endl;

//значение переменной увеличим на 1

Numb++;

//переменная имеет значение максимального отрицательного

cout<<" Значение Numb:"<<Numb<<endl;

Numb++;

cout<<" Новое значение Numb:"<<Numb<<endl;

return 0;

}

 

Результат:

Значение Numb: 32 767

Значение Numb: -32 768

Значение Numb: -32 767

 

Операторы С++. Базовые конструкции структурного программирования, условный оператор.

Объединение оператора присвоения и арифметических операторов. Любаяинструкция типа Sum = Sum + I, смысл которой состоит в увеличении переменной Sum на величину i, и присвоении результата переменной Sum, может быть записана:

Sum + = i

Оператор присвоения с суммой («+ =») добавляет r-значение к l-значению, а затем присваивает результат l-значению. Если бы до начала выполнения выражения значение переменной Sum было равно 21, а i рано 1, то результат оказался бы равным 22.

Все арифметические операторы позволяют использовать такую же запись:

 

x = x * i ® x * = i

x = x / i ® x / = i

x = x % i ® x % = i

 

Инкремент и декремент. Если оператор «+ =» применить в инструкции увеличения переменной на 1 (инкремент) или уменьшения переменной на 1 (декремент), что в программах встречается очень часто, то можно записать вместо выражения i + = 1выражение i ++ , а вместо выражения i - = – i --.

 

Пример. Рассмотрим программу:

#include <iostream>

using namespace std;

int main( ) {

int N=2000000;

int sum=0, i=1;

while (i<N) {

sum = sum + i;

i=i+1; }

cout<<"sum="<<sum<<endl;

return 0;}

 

Тело функции main( ) в этой программе может быть записано:

int main( ){

int N=2000000;

int sum=0, i=1;

while (i<N)

sum += i++;

cout<<"sum="<<sum<<endl;

return 0;}

 

Операторы инкремента и декремента существуют в двух вариантах: префиксном и постфиксном. Префиксный вариант записывается перед именем переменной (+=sum), а оператор увеличения значения вычисляется до присвоения. Постфиксный записывается после имени переменной (sum +=), оператор выполняется после присвоения.

Другими словами смысл префиксного оператора: изменить значение, а затем присвоить его. Смысл постфиксного: присвоить значение, а затем изменить его оригинал.

#include <iostream>

using namespace std;

int main( ){

int i=1, j=1;

int sumPr =++i;

int sumPst = j++;

cout<<" Prefics sum="<<sumPr<<endl;

cout<<" Postfics sum="<<sumPst<<endl;

return 0;}

 

Выражение int sumPr =++i; сообщает компилятору, что переменную i необходимо увеличить на 1, сделав ее равной 2, а затем присвоить это значение переменной sumPr. Выражение же int sumPst = j++; предписывает компилятору сначала присвоит переменной sumPst текущее значение переменной j (j=1) и только после этого увеличить j на единицу. Следовательно результат работы программы:

Prefics sum= 2

Postfics sum= 1

 

Логические операторы для программирования сложных условий. Для обозначения результатов логических выражений в стандарте ANSI применяется тип bool, имеющий только два возможных значения: true (истина – для определения равенства двух значений) и false (ложь – для определения неравенства двух значений). Тогда результатом любого логического выражения может быть либо истина, либо ложь. Выражение, содержащее операторы отношения (выражения сравнения) всегда возвращают значения true либо false. Математические выражения, возвращающие ноль, можно рассматривать как значение false, а любой другой результат как true.

Случается так, что программа выполнит какое-то действие только в случае соблюдения двух и большего числа условий. Например, для попадания в какой-то интервал переменная должна быть одновременно больше чего-то одного и меньше чего-то другого

0 <x<1. Поэтому в языке С++ есть специальные операторы, помогающие записывать сложные условия. Например, условие попадания числа x в указанный интервал запишется как x >9 && x < 10. В нем сначала проводятся сравнения x >9 и x < 10, потому, что приоритет операторов <>, выше, чем оператора &&, а затем с результатом сравнений работает оператор. Оператор && называется логическим (логическое AND). Кроме него существуют еще два логических оператора, они приведены в Таблице 3.

Таблица 3

Оператор Символ Пример
AND (И) && выражение1 && выражение2
OR (ИЛИ) | | выражение1 | | выражение2
NOT (НЕ) ! ! выражение

 

Оператор AND (И) двухаргументный (оценивает два операнда). Результат оператора:

  • (истина) AND (истина) есть истина;
  • (истина) AND (ложь) есть ложь;
  • (ложь) AND (истина) есть ложь;

 

Например, логическое выражение в составе оператора условия

if ( (x = = 5) && (y = = 5) )

возвратит значение true только в том случае, если x и y равны числу 5 и false, если хотя бы одна из переменных не равна 5.

Оператор OR ( ИЛИ) двухаргументный. Результат оператора:

  • (истина) OR (истина) есть истина;
  • (истина) OR (ложь) есть истина;
  • (ложь) OR (истина) есть истина;
  • (ложь) OR (ложь) есть ложь

Например, логическое выражение в составе оператора условия

if ( (x = = 5) | | (y = = 5) )

возвратит значение true в том случае, если хотя бы одна их переменных x и y равна числу 5 или они обе равны 5, и false, если обе переменные не равны 5.

Оператор NOT является одноаргументным (оценивает только один операнд). Результат противоположен значению операнда:

  • NOT(истина) есть ложь;
  • NOT(ложь) есть истина

Например, логическое выражение в составе оператора условия

if ( ! (x = = 5))

возвратит значение true только в том случае, если x не равен числу 5. Это выражение можно записать и по-другому:

if (x != 5)

 








Не нашли, что искали? Воспользуйтесь поиском по сайту:



©2015 - 2024 stydopedia.ru Все материалы защищены законодательством РФ.