Файл: Функции и массивы. Аргументы командной строки. Студент ki 1221рус.doc
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 25.04.2024
Просмотров: 4
Скачиваний: 0
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
Функции и массивы. Аргументы командной строки.
Студент KI 12-21рус
Шаропов С.О.
Массив в С++ никогда не передается по значению, а только как указатель на его первый (т.е. имеющий индекс 0) элемент. Все три следующие объявления функций эквивалентны:
void sort( int * );
void sort( int[] );
void sort( int[10] );
Таким образом, передача массивов имеет следующие особенности:
При изменении значения аргумента внутри функции будет изменен сам переданный массив, а не его локальная копия. Если это не желательно, то можно явным образом при объявлении функции указать, что она не должна менять значение аргумента, объявив его константным:
int sum( const int[] );
Размер массива не является частью типа параметра, поэтому функция «не знает» реального размера переданного ей массива. Передавать размер массива необходимо явным образом, например:
int sum( const int A[], unsigned int size );
Исключением являются только функции, работающие с С-строками, представляющими собой массивы символов, явно содержащие в себе признак своего конца в виде нуль-символа.
Другой способ явно сообщить функции размер массива-параметра – объявить его как ссылку. В этом случае, размер становится частью типа, и компилятор сможет проверить аргумент полностью. Само собой, такая реализация существенно ограничивает область применения функции только массивами заранее заданного размера:
const int A_SIZE = 10;
int sum( const int ( & A ) [ A_SIZE ] )
{
int s = 0;
for ( int i = 0; i < A_SIZE; ++i )
s += A[i];
return s;
}
void main()
{
int A[ 10 ] = {1,2,3,4,5,6,7,8,9,0};
cout << sum( A ) << endl; // допустимо, размер совпадает с A_SIZE
int B[ 5 ] = {1,2,3,4,5};
sum(B); // ошибка, размер неверный
}
Для параметров-многомерных массивов должны быть заданы правые границы всех его измерений, кроме первого:
int sum( int M[][10], int rows );
Здесь M объявлен как двумерный массив, содержащий десять столбцов и неизвечтное число строк. Эквивалентное объявление:
int sum( int ( * M )[10], int rows );
В этом случае скобки вокруг * M необходимы из-за более высокого приоритета операции взятия индекса.
Многомерный массив передается как указатель на его нулевой элемент. В нашем случае тип M – указатель на массив из десяти элементов типа int. Как и для одномерного массива, граница первого измерения не учитывается при проверке типов. Если параметры являются многомерными массивами, то контролируются все измерения, кроме первого.
Многомерные массивы в динамической памяти представлят собой иерархию типа «массив указателей на указатели...», поэтому для передачи их в функцию используются двойные (тройные и т.п.) указатели. Следующий пример реализует набор простых функций для работы с квадратными матрицами:
// Функция выделяет память под квадратную матрицу
// требуемого размера и возвращает указатель
int ** allocateMatrix( int size )
{
int ** M = new int * [ size ];
for ( int i = 0; i < size; ++i )
{
M[i] = new int[ size ];
}
return M;
}
// Функция освобождает память, занимаемую
// квадратной матрицей заданного размера
void freeMatrix( int ** M, int size )
{
for ( int i = 0; i < size; ++i )
delete[] M[i];
delete[] M;
}
// Функция заполняет квадратную матрицу
// случайными числами (0
100)
void fillMatrix( int ** M, int size )
{
for ( int i = 0; i < size; ++i )
{
for ( int j = 0; j < size; ++j )
{
M[i][j] = rand() % 100;
}
}
}
// Функция транспонирует квадратную матрицу
void transposeMatrix( int ** M, int size )
{
for ( int i = 0; i < size; ++i )
{
for ( int j = 0; j < i; j++ )
{
int tmp = M[i][j];
M[i][j] = M[j][i];
M[j][i] = tmp;
}
}
}
// Функция выводит матрицу на экран
void displayMatrix( const int ** M, int size, char * prefix = NULL )
{
if ( prefix )
std::cout << prefix << std::endl;
for ( int i = 0; i < size; ++i )
{
for ( int j = 0; j < size; ++j )
std::cout << M[i][j] << " ";
std::cout << std::endl;
}
}
int main( int argc, char *argv[] )
{
// Задали размер
int size = 5;
// Выделили память
int ** M = allocateMatrix( size );
// Заполнили матрицу случаными числами
fillMatrix( M, size );
// Выводим исходную матрицу
displayMatrix( M, size, "Initial:" );
// Транспонируем матрицу
transposeMatrix( M, size );
// Выводим транспонированную матрицу
displayMatrix( M, size, "Transposed:" );
// Освобождаем память
freeMatrix( M, size );
system( "pause" );
}
Аргументы командной строки.
При запуске консольной программы, как правило, информация ей передается в командной строке в виде строки параметров. Например, для копирования файлов стандартной программой copy нужно в качестве параметров передать имена файлов:
copy c:\1.txt d:\2.txt
Указанные параметры командной строки передаются в основную функцию main и могут быть получены из массива С-строк с именем argv. Количество параметров передается через аргумент argc. Развернутый прототип функции main будет выглядеть следующим образом:
int main( int argc, char *argv[] )
В первом элементе массива строк argv (с индексом 0) всегда будет передаваться имя исполняемого файла, а все остальные элементы (с индексами от 1 до argc-1) будут содержать параметры (в командной строке они разделяются пробелами). Следующий пример иллюстрирует работу с параметрами командной строки. Программа создает файл с указанным именем и заполняет его заданным символом в заданном количестве:
int main( int argc, char *argv[] )
{
// В командной строке не передали имя файла
if ( argc < 2 )
{
std::cout << "Необходимо указать имя файла!" << std::endl;
return 0;
}
// Имя файла
char * fname = argv[1];
// Используемый символ, по умолчанию - 'A'
char symbol = 'A';
// Ограничение на максимально допустимое число символов
const int MAX_COUNT = 256;
// Требуемое количество символов, по умолчанию - максимум
int count = MAX_COUNT;
// Если в командной строке передали символ - используем его
if ( argc >= 3 )
symbol = argv[2][0];
// Если в командной строке передали количество - используем его
if ( argc >= 4 )
count = std::min( atoi( argv[3] ), MAX_COUNT );
if ( count < 0 )
{
cout << "Ошибка, недопустимое количество символов!" << endl;
return 0;
}
ofstream f( fname );
if ( ! f )
{
cout << "Ошибка создания файла!" << endl;
return 0;
}
cout << "Заполняем файл " << fname << " " << count << " символами " << symbol << endl;
for ( int i = 0; i < count; ++i )
f << symbol << " ";
f.close();
cout << "Готово!" << endl;
}