- •Битовые операции
- •Битовые логические операции
- •Битовые операции сдвига
- •Логические операции
- •Битовые операции
- •Логические операции
- •Символьный тип
- •Целочисленный тип
- •Вещественный тип
- •Логический тип
- •Преобразование типов данных
- •Оператор цикла while
- •Оператор цикла for
- •Оператор цикла do while
- •Программирование вложенных циклов
- •Переприсваивание
- •Объединение строк
- •Escape-знаки
- •Точные строки: символ @
- •Преобразование строк в другие типы
- •Объединения
- •Основные понятия
- •7.2. Определение функции
- •Вызов функции
- •Передача данных по значению
- •Передача данных по адресу
- •Передача данных по ссылке
- •Передача одномерного массива в функцию
- •Вызовы с переменным числом аргументов
- •Определение значений по умолчанию
- •Организация работы с файлами средствами c
- •Файловый ввод-вывод с использованием потоков
- •Инкапсуляция
- •Наследование
- •Полиморфизм
- •Массивы указателей
- •Предварительная инициализация параметров функции
- •Динамические массивы ограниченного размера и их объём[]
- •Макроопределение - директива #define
- •Структура библиотеки
- •Бщее описание[править | править исходный текст]
- •Неструктурная обработка исключений[
- •Структурная обработка исключений[
Массивы указателей
Можно создавать массивы указателей. Для объявления массива целочисленных указателей из десяти элементов следует написать: int *х[10]; Для присвоения адреса целочисленной переменной var третьему элементу массива следует написать: х[2] = &var; Для получения значения var следует написать: *х [2]
Если необходимо передать массив указателей в функцию, можно использовать метод, аналогичный передаче обычных массивов. Просто надо вызвать функцию с именем массива без индексов. Например, функция, получающая массив х, должна выглядеть следующим образом: void display_array(int *q[]) { int t; for(t=0; t<10; t++) printf ("%d ", *q[t]); } Надо помнить, что q - это не указатель на целое, а массив указателей на целые. Следовательно, необходимо объявить параметр q как массив целых указателей. Он не может объявиться как простой целочисленный указатель, поскольку он не является им.
Предварительная инициализация параметров функции
Список параметров в определении и прототипе функции, кроме согласования типов параметров, имеет ещё одно назначение.
Объявление параметра может содержать инициализатор, то есть выражение, которое должно обеспечить параметру присвоение начального значения. Инициализатор параметра не является константным выражением. Начальная инициализация параметров происходит не на стадии компиляции (как, например, выделение памяти под массивы), а непосредственно в ходе выполнения программы.
Следующие строки демонстрируют пример объявления функции с инициализацией параметров. Для инициализации параметра ww используется функция XX.
int BigVal; int XX(int); int ZZ(int tt, int ww = XX(BigVal));
Второй параметр можно проинициализировать и таким способом, вовсе не указывая его имени. Синтаксис объявления позволяет сделать и такое!
int ZZ(int tt, int = XX(BigVal));
Единственное условие подобной инициализации - соответствие типа параметра и типа выражения, значение которого используется при начальной инициализации.
Прототипы функции могут располагаться в различных областях видимости. Его можно даже разместить в теле определяемой функции. Каждое объявление функции может содержать собственные варианты объявления и инициализации параметров. Но во множестве объявлений одной и той же функции в пределах одной области видимости не допускается повторная инициализация параметров. Всему должен быть положен разумный предел.
Кроме того, в C++ действует ещё одно ограничение, связанное с порядком инициализации параметров в пределах области видимости. Инициализация проводится непременно с самого последнего (самого правого) параметра в списке объявлений параметров. Инициализация параметров не допускает пропусков: инициализированные параметры не могут чередоваться с параметрами неинициализированными.
int MyF1 (int par1, int par2, int par3, int par4 = 10); int MyF1 (int par1, int par2 = 20, int par3 = 20, int par4); int MyF1 (int par1 = 100, int, int, int);
Список параметров в определении функции строится по аналогичным правилам. В списке параметров определения функции также допускаются инициализаторы, в ряде случаев также могут быть опущены имена параметров. Разумеется, включение в заголовок определения функции безымянного параметра затрудняет возможность использования этого параметра в определяемой функции. К безымянному параметру невозможно обращаться по имени.
И всё же отказ от использования параметра может быть оправдан. Такие параметры, вернее их спецификаторы, позволяют сократить затраты на модификацию сложных многомодульных программ, когда в результате изменения функции меняется число параметров этой функции. Ненужные параметры могут быть отключены без изменения многочисленных вызовов этой функции. В этом случае имеет смысл сохранить общее количество параметров функции, а имя ненужного параметра из списка параметров удалить.
33передача параметров функции main c++
При создании консольного приложения в языке программирования С++, автоматически создается строка очень похожая на эту:
1 |
int main(int argc, char* argv[]) // параметры функции main() |
Эта строка — заголовок главной функции main(), в скобочках объявлены параметры argс и argv. Так вот, если программу запускать через командную строку, то существует возможность передать какую-либо информацию этой программе, для этого и существуют параметры argc и argv[]. Параметр argc имеет тип данных int, и содержит количество параметров, передаваемых в функцию main. Причем argc всегда не меньше 1, даже когда мы не передаем никакой информации, так как первым параметром считается имя функции. Параметр argv[] это массив указателей на строки. Через командную строку можно передать только данные строкового типа. Указатели и строки — это две большие темы, под которые созданы отдельные разделы. Так вот именно через параметр argv[] и передается какая-либо информация. Разработаем программу, которую будем запускать через командную строку Windows, и передавать ей некоторую информацию.
Время жизни и область видимости программных объектов Классы памяти.
Время жизни переменной (глобальной или локальной) определяется по следующим правилам.
1. Переменная, объявленная глобально (т.е. вне всех блоков), существует на протяжении всего времени выполнения программы.
2. Локальные переменные (т.е. объявленные внутри блока) с классом памяти register или auto, имеют время жизни только на период выполнения того блока, в котором они объявлены. Если локальная переменная объявлена с классом памяти static или extern, то она имеет время жизни на период выполнения всей программы.
Видимость переменных и функций в программе определяется следующими правилами.
1. Переменная, объявленная или определенная глобально, видима от точки объявления или определения до конца исходного файла. Можно сделать переменную видимой и в других исходных файлах, для чего в этих файлах следует ее объявить с классом памяти extern.
2. Переменная, объявленная или определенная локально, видима от точки объявления или определения до конца текущего блока. Такая переменная называется локальной.
3. Переменные из объемлющих блоков, включая переменные объявленные на глобальном уровне, видимы во внутренних блоках. Эту видимость называют вложенной. Если переменная, объявленная внутри блока, имеет то же имя, что и переменная, объявленная в объемлющем блоке, то это разные переменные, и переменная из объемлющего блока во внутреннем блоке будет невидимой.
4. Функции с классом памяти static видимы только в исходном файле, в котором они определены. Всякие другие функции видимы во всей программе.
Метки в функциях видимы на протяжении всей функции.
Имена формальных параметров, объявленные в списке параметров прототипа функции, видимы только от точки объявления параметра до конца объявления функции.
Классы памяти в с++.
Существует 4 спецификатора класса памяти:
1)auto
2)register
3)static
4)extern
Если класс памяти не указан, он определяется по умолчанию из контекста объявления.
Объекты классов auto и register имеют локальное время жизни.
Спецификаторы static и extern определяют объекты с глобальным временем жизни, но точный смысл каждого спецификатора зависит от того, находится ли он на внешнем или на внутреннем уровне и от того, является ли объект функцией или переменной.
На внутреннем уровне при объявлении переменной может быть использован любой из 4 спецификаторов класса памяти. Если спецификатор опущен, то подразумевается auto
fun()
{
int i; -> auto int i;
Переменная с классом памяти auto имеет локальное время жизни. Она видима только в том блоке, в котором объявлена. Память для этой переменной выделяется при входе в блок и освобождается при выходе. При повторном входе в блок память для этой переменной может быть распределена в другом месте.
Классы памяти в с++.
Существует 4 спецификатора класса памяти:
1)auto
2)register
3)static
4)extern
Если класс памяти не указан, он определяется по умолчанию из контекста объявления.
Объекты классов auto и register имеют локальное время жизни.
Спецификаторы static и extern определяют объекты с глобальным временем жизни, но точный смысл каждого спецификатора зависит от того, находится ли он на внешнем или на внутреннем уровне и от того, является ли объект функцией или переменной.
На внутреннем уровне при объявлении переменной может быть использован любой из 4 спецификаторов класса памяти. Если спецификатор опущен, то подразумевается auto
fun()
{
int i; -> auto int i;
Переменная с классом памяти auto имеет локальное время жизни. Она видима только в том блоке, в котором объявлена. Память для этой переменной выделяется при входе в блок и освобождается при выходе. При повторном входе в блок память для этой переменной может быть распределена в другом месте.
register
Предписывает компилятор распределить память под переменную в регистре процессора, если это возможно. Переменная с классом памяти register имеет ту же область видимости, что и auto.
Когда компилятор встречает спецификатор register, а свободного регистра не имеется, то для переменной распределяется память auto.
Регистровая память, если она имеется, может быть назначена только для переменной типа int и указателей.
static
Переменные, объявленные на внутреннем уровне со спецификатором static, обеспечивают возможность сохранить значение локальной переменной при выходе из блока и использовать его при следующем входе в блок.
extern
Переменная, объявленная со спецификатором extern, является ссылкой на переменную с тем же именем, определенную на внешнем уровне в любом исходном файле программы.
Цель объявления extern состоит в том, чтобы сделать объявление переменной внешнего уровня видимой внутри блока.
35Инициализация глобальных и локальных переменных
Существуют локальные и глобальные переменные. Так вот, переменные, объявленные внутри функции, называются локальными. Локальные переменные имеют свои области видимости, этими областями являются функции, в которых объявлены переменные. Таким образом, в разных функциях можно использовать переменные с одинаковыми именами, что в свою очередь очень удобно. Разделение переменных на глобальные и локальные соответствует одному из главных правил программирования, а именно – принципу наименьших привилегий. То есть, переменные, объявленные внутри одной функции, должны быть доступны только для этой функции и ни чему другому, в конце концов, они создавались именно для этой функции. Глобальные переменные объявляются вне тела какой-либо функции, и поэтому область видимости таких переменных распространяется на всю программу. Обычно глобальные переменные объявляются перед главной функцией, но можно объявлять и после функции main(), но тогда данная переменная не будет доступна в функции main().
Разработаем программу, в которой будут объявлены две переменные, локальная и глобальная, с одинаковым именем.
37Динамические массивы. Особенности выделения и освобождения памяти для многомерных массивов.
Динамическим называется массив, размер которого может меняться во время исполнения программы. Для изменения размера динамического массива язык программирования, поддерживающий такие массивы, должен предоставлять встроенную функцию или оператор. Динамические массивы дают возможность более гибкой работы с данными, так как позволяют не прогнозировать хранимые объёмы данных, а регулировать размер массива в соответствии с реально необходимыми объёмами. В отличие от динамических массивов существуют статические массивы и массивы переменной длины. Размер статического массива определяется на момент компиляции программы. Размер массива переменной длины определяется во время выполнения программы. Отличием динамического массива от массива переменной длины является автоматическое изменение размеров, что не трудно реализуется в случаях его отсутствия, поэтому часто не различают массивы переменной длины с динамическими массивами.
