Файл: Функции и массивы. Аргументы командной строки. Студент 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;

}