Операции в языке Си

Арифметические операции и их особенности в языке С. Основные типы данных, операции и выражения. Константы с плавающей точкой. Базовые типы переменных в C. Сложение и вычитание числовых значений из указателей. Операции над структурами и объединениями.

Рубрика Программирование, компьютеры и кибернетика
Вид шпаргалка
Язык русский
Дата добавления 23.06.2011
Размер файла 122,8 K

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Между именем массива и указателем, выступающим в роли имени массива, существует одно различие. Указатель - это переменная, поэтому можно написать pa=a или pa++. Но имя массива не является переменной, и записи вроде a=pa или a++ не допускаются.

Если имя массива передается функции, то последняя получает в качестве аргумента адрес его начального элемента. Внутри вызываемой функции этот аргумент является локальной переменной, содержащей адрес. Мы можем воспользоваться отмеченным фактом и написать еще одну версию функции strlen, вычисляющей длину строки.

/* strlen: возвращает длину строки */

int strlen(char *s)

{

int n;

for (n = 0; *s != '\0'; s++)

n++;

return n;

}

Так как переменная s - указатель, к ней применима операция ++; s++ не оказывает никакого влияния на строку символов функции, которая обратилась к strlen. Просто увеличивается на 1 некоторая копия указателя, находящаяся в личном пользовании функции strlen. Это значит, что все вызовы, такие как

strlen("3дравствуй, мир"); /* строковая константа */

strlen(array); /* char array[100]; */

strlen(ptr); /* char *ptr; */

правомерны.

Формальные параметры

char s[];

и

char *s;

В определении функции эквивалентны. Мы отдаем предпочтение последнему варианту, поскольку он более явно сообщает, что s есть указатель. Если функции в качестве аргумента передается имя массива, то она может рассматривать его так, как ей удобно - либо как имя массива, либо как указатель, и поступать с ним соответственно. Она может даже использовать оба вида записи, если это покажется уместным и понятным.

Функции можно передать часть массива, для этого аргумент должен указывать на начало подмассива. Например, если a - массив, то в записях

f(&a[2])

или

f(a+2)

функции f передается адрес подмассива, начинающегося с элемента a[2]. Внутри функции f описание параметров может выглядеть как

f(int arr[]) {...}

или

f(int *arr) {...}

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

Если есть уверенность, что элементы массива существуют, то возможно индексирование и в "обратную" сторону по отношению к нулевому элементу; выражения p[-1], p[-2] и т.д. не противоречат синтаксису языка и обращаются к элементам, стоящим непосредственно перед p[0]. Разумеется, нельзя "выходить" за границы массива и тем самым обращаться к несуществующим объектам.

Билет № 17

1). Операция sizeof

С помощью операции sizeof можно определить размер памяти которая соответствует идентификатору или типу. Операция sizeof имеет следующий формат:

sizeof(выражение)

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

Если в качестве выражения указанно имя массива, то результатом является размер всего массива (т.е. произведение числа элементов на длину типа), а не размер указателя, соответствующего идентификатору массива.

Когда sizeof применяются к имени типа структуры или объединения или к идентификатору имеющему тип структуры или объединения, то результатом является фактический размер структуры или объединения, который может включать участки памяти, используемые для выравнивания элементов структуры или объединения. Таким образом, этот результат может не соответствовать размеру, получаемому путем сложения размеров элементов структуры.

Пример:

struct { char h; int b; double f; } str; int a1; a1 = sizeof(str);

Переменная а1 получит значение, равное 12, в то же время если сложить длины всех используемых в структуре типов, то получим, что длина структуры str равна 7.

Несоответствие имеет место в виду того, что после размещения в памяти первой переменной h длинной 1 байт, добавляется 1 байт для выравнивания адреса переменной b на границу слова (слово имеет длину 2 байта для машин серии IBM PC AT /286/287), далее осуществляется выравнивание адреса переменной f на границу двойного слова (4 байта), таким образом в результате операций выравнивания для размещения структуры в оперативной памяти требуется на 5 байт больше.

В связи с этим целесообразно рекомендовать при объявлении структур и объединения располагать их элементы в порядке убывания длины типов, т.е. приведенную выше структуру следует записать в следующем виде:

struct { double f; int b; char h; } str;

2). Поля бит

Элементом структуры может быть битовое поле, обеспечивающее доступ к отдельным битам памяти. Вне структур битовые поля объявлять нельзя. Нельзя также организовывать массивы битовых полей и нельзя применять к полям операцию определения адреса. В общем случае тип структуры с битовым полем задается в следующем виде

struct { unsigned идентификатор 1 : длина-поля 1; unsigned идентификатор 2 : длина-поля 2; }

длина - поля задается целым выражением или константой. Эта константа определяет число битов, отведенное соответствующему полю. Поле нулевой длины обозначает выравнивание на границу следующего слова.

Пример:

struct { unsigned a1 : 1; unsigned a2 : 2; unsigned a3 : 5; unsigned a4 : 2; } prim;

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

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

Билет № 18

1). Сложение и вычитание числовых значений из указателей

Можно сложить значение n типа int, uint, long или ulong с указателем p, любого типа, кроме void*. В результате p+n получится указатель, являющийся суммой n * sizeof(p) to the address of p. Аналогично, результатом p-n является указатель, полученный вычитанием n * sizeof(p) из адреса p.

Вычитание указателей

Также можно вычитать указатели одного типа.

Тип результата всегда long. Например, если p1 и p2 являются указателями типа pointer-type*, то результат выражения p1-p2 будет следующим:

((long)p1 - (long)p2)/sizeof(pointer_type)

При переполнении домена указателя в результате выполнения арифметической операции исключений не генерируется, а результат зависит от конкретной реализации.

2). Перечисления

Есть способ связывания имен с целыми константами, который часто более удобен, чем описание с const.

Например:

enum { ASM, AUTO, BREAK };

Здесь определены три целых константы, которые называются элементами перечисления, и им присвоены значения.

Поскольку по умолчанию значения элементов перечисления начинаются с 0 и идут в возрастающем порядке, то приведенное перечисление эквивалентно определениям:

const ASM = 0;

const AUTO = 1;

const BREAK = 2;

Перечисление может иметь имя, например:

enum keyword { ASM, AUTO, BREAK };

Имя перечисления становится новым типом. С помощью стандартных преобразований тип перечисления может неявно приводиться к типу int. Обратное преобразование (из типа int в перечисление) должно быть задано явно.

Например

void f()

{

keyword k = ASM;

int i = ASM;

k = i // ошибка

k = keyword(i);

i = k;

k = 4; // ошибка

}

Последнее преобразование поясняет, почему нет неявного преобразования из int в перечисление: большинство значений типа int не имеет представления в данном перечислении. Описав переменную с типом keyword вместо очевидного int, мы дали как пользователю, так и транслятору определенную информацию о том, как будет использоваться эта переменная. Например, для следующего оператора

keyword key;

switch (key) {

case ASM:

// выполнить что-либо

break;

case BREAK:

// выполнить что-либо

break;

}

транслятор может выдать предупреждение, поскольку из трех возможных значений типа keyword используются только два.

Значения элементов перечисления можно задавать и явно.

Например:

enum int16 {

sign=0100000,

most_significant=040000,

least_significant=1

};

Задаваемые значения необязательно должны быть различными, положительными и идти в возрастающем порядке.

Билет № 19

2). Типы переменных

Надеюсь вы знаете что такое переменная, если нет прочитайте тут первый абзац :]

итак базовые типы переменных в C++:

тип размер (байт) минимальное значение максимальное значение

unsigned short int 2 0 65535

short int 2 -32768 32767

unsigned long int 4 0 4294967295

long int 4 -2147483648 2147483647

int (16 bit) 2 -32,768 32767

int (32 bit) 4 -2147483648 2147483647

unsigned int (16 bit) 2 0 65535

unsigned int (32 bit) 2 0 4294967295

char 1 256 символов

float 4 1.2e-38 3.4e38

double 8 2.2e-308 1.8e308

Переменные типа int могут иметь размер 2 или 4 байта в зависимости от компилятора и системы компьютера(16 или 32-разрадная).Узнать размер переменной(объекта) данного типа можно с помощью функции sizeof(),

Например:

cout<<"int: "<<sizeof(int)<<" char: "<<sizeof(char);

выведет:

int: 4 char: 1

т.е. переменная типа int имеет размер 4 байта а char 1 байт.

Перед тем как использовать переменную в C++ надо ее объявить.

Для этого указывается тип переменной и ее имя, например:

int a ;

Можно объявить несколько переменных одногог типа в одной строке:

int a , b, c ;

Можно инициализировать(присвоить значение) переменной при объявлении:

int a, b=1, c=10, d ;

При попытке присвоить переменной значение превышающее максимально допустимое,то достигнув максимального значения отсчет начинается с минимального значения.

Например:

unsigned short int n; n=65535; cout<<"n="<<n<<endl; n=n+10; cout<<"n="<<n<<endl;

результат:

n=65535

n=9

Константы

Константы как и переменные предназначены для хранения данных,но в отличие от переменных должны инициализироваться при объявлении и им нельзя присвоить новое значение.Константы можно определить двумя способами:

#define MyConstant 10 ( о директиве #define см. тут)

const int MyOtherConstant = 10 ;

Предпочтительнее использовать второй способ так как при определении константы с помощью #define она не имеет типа,а тип константы вам может понадобиться.

Перечисления:

с помощью перечислений можно создать тип переменных которые могут принимать только определенные вами значения.Для создания перечисления используется слово enum затем имя типа и список допустимых значений в фигурных скобках.

enum color { red,green,blue };

при этом создается новый тип color и определяются константы red=0,green=1,blue=2

если обявить переменную типа color

color a_color ;

то она может принимать только значения red green и blue (т.е. 0,1,2)

По умолчанию, если константы перечисления не инициализировать то первой из них присваивается значение 0 и каждая последующая константа принимает значение на 1 больше предыдушей.Любую константы можно инициализировать произвольным значением, при этом неинициализированные константы будут принимать значения на 1 больше предыдушей.

Например при объявлении:

num color { red=5,green,blue, yellow=100,black};

константы будут иметь следующие значения:

red=5,green=6,blue=7,yellow=100,black=101.

typedef:

typedef используется для создания псевдонима типа данных, например если вам лень каждый раз при определении беззнакового целого писать unsigned short int то можно создать псевдоним для этой “фразы”:

typedef unsigned short int US ;

после этого если вам нужно создать новую переменную вместо unsigned short int n просто пишете:

US n ;

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

Билет № 20

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

Инициализация глобальных и статических переменных производится однократно. Инициализация локальных переменных производится каждый раз при вызове соответствующих функций.

Примеры:

int n = 1;

double p = MarketInfo(Symbol(),MODE_POINT);

string s = "hello";

double f[] = { 0.0, 0.236, 0.382, 0.5, 0.618, 1.0 };

int a[4][4] = { 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4 };

Список значений элементов массива должен быть заключен в фигурные скобки. Пропущенные инициализирующие значения считаются равными 0. Если размер инициализируемого массива не указан, то он определяется компилятором, исходя из размера инициализирующей последовательности. Многомерные массивы инициализируются одномерной последовательностью, последовательностью без дополнительных фигурных скобок. Массивы (в том числе и объявленные на локальном уровне) могут инициализироваться только константами.

Билет № 21

1). Программа на языке С++ представляет собой набор функций. Одна из функций должна иметь имя main. Операционная система передает управление в программу пользователя на функцию с этим именем и тем самым начинается выполнение программы. От функций в программе функция main отличается тем, что ее нельзя вызвать изнутри программы, а ее параметры, если они существуют, обычно задаются ОС, хотя это необязательно, main бывает первой функцией в тексте программы.

main ( )

{

...

return 0;

}

Если предположить, что main- первая функция, определенная в программе на языке С++, то поскольку ни одна функция не может содержать определения другой функции, следом в тексте будут располагаться определения вспомогательных функций, «неглавных» функций. Их может быть различное количество.

main ( )

{

...

return 0;

}

function 1 ( )

{

}

function 2 ( )

{

}

...

function n ( )

{

}

Функции могут быть описаны в произвольном порядке. Удобно расположить их по алфавиту или сгруппировать по определенному признаку.

Размещено на Allbest.ru


Подобные документы

  • Двоично-десятичный формат (BCD - Binary Coded Decimal). Преобразование ASCII формата в двоичный формат. Арифметические инструкции и флаги. Форматы арифметических данных. Выполнение арифметических операции. Сложение. Вычитание. Умножение. Деление.

    доклад [16,2 K], добавлен 22.09.2008

  • Операции, осуществляемые при реализации алгоритмов цифровой обработки сигналов. Применение процессора ADSP-2106x для операций с фиксированной и плавающей точкой. Исключения при выполнении операций с плавающей точкой, режимы и границы округления.

    реферат [35,2 K], добавлен 13.11.2009

  • Арифметические операции с целыми числами. Сложение и вычитание в дополнительном коде. Представление чисел в формате с плавающей точкой. Особенности выполнения арифметических операций в соответствии с IEEE. Точность выполнения арифметических операций.

    контрольная работа [5,6 M], добавлен 19.05.2010

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

    контрольная работа [533,1 K], добавлен 23.04.2010

  • Организация и назначение консольного ввода-вывода, необходимые для этого функции и их применение. Библиотеки, организующие функционирование потокового ввода-вывода, выполняемые операции. Арифметические операции и математические функции в среде С++.

    лабораторная работа [33,8 K], добавлен 15.07.2009

  • Основные понятия и назначение языка программирования СИ. Скалярные типы данных. Арифметические, логические и битовые операции над переменными целочисленного, вещественного, символьного, перечислимого типов. Примеры программ, выполняющие операции над ними.

    презентация [269,9 K], добавлен 26.07.2013

  • Основные форматы данных и их представление. Запись чисел в формат с плавающей точкой. Вычитание чисел в формате с плавающей точкой. Регистры операндов и результата, размером формата числа с плавающей точкой, двойной точности. Поля смещённого порядка.

    курсовая работа [78,9 K], добавлен 09.09.2014

  • Типы численных данных с фиксированной точкой и основные операции обращения с ними. Целые двоичные числа: классификация, особенности, основные понятия. Наработка практических навыков обращения с целыми числами на компьютере (запись, считывание, хранение).

    контрольная работа [24,8 K], добавлен 12.03.2011

  • Общее описание функций Oracle SQL, их особенности, классификация и типы, преобразование регистра символов и манипулирование строками. Работа со строковыми функциями. Арифметические операции с датами. Функции преобразования и основные операции над ними.

    курсовая работа [464,4 K], добавлен 24.12.2014

  • Изучение методов и этапов создания класса Complex, позволяющего работать с комплексными числами и производить с ними следующие операции: сложение, вычитание, умножение, деление двух комплексных чисел. Написание кода для ввода и вывода исходных данных.

    курсовая работа [628,4 K], добавлен 11.09.2010

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.