Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции.docx
Скачиваний:
1
Добавлен:
01.07.2025
Размер:
933 Кб
Скачать
☆

Передача массивов

C

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

При объявлении float a[10][10] обращение вида: <имя_функции>(a) эквивалентно обращению: <имя_функции>(&a[0][0]). Следовательно, массивы-параметры занимают память, отводимую в вызывающей процедуре массивам-аргументам, поэтому в прототипе и вызываемой процедуре допустимы их описания вида float b[ ], a[ ][10]; Длины всех измерений, кроме первого, надо задавать, чтобы правильно извлечь из памяти значения нужного элемента массива (см. формулу в параграфе "Распределение массивов"). Допустимо даже несоответствие размерностей аргумента и параметра.

Пример.

Аргументы Параметры

float a[5][5], b[36]; float a[ ], b[ ][6];

Пример. Вычислить: z=uТbu, где {ui]}, i=1...4; {bij]}, i,j=1...4.

/* Вычисление квадратичной формы */

int main( ){

float u[4], // Входной вектор

b[4][4], // Входная матрица

v[4], // Вектор b*u

scalar(float [ ], float [ ]);// Скалярное произведение векторов

int i, j;

/* Умножение матрицы на вектор */

void matrix(float [ ][4], float [ ], float [ ]);// Прототип

printf("Исходный вектор:\n");

for(i=0; i<4; i++){

scanf("%f", &u[ i ]);

}

printf("Исходная матрица:\n");

for(i=0; i<4; i++){

for(j=0; j<4; j++){

scanf("%f", &b[ i ][ j ]);

}

}

matrix(b, u, v);

printf("\n\n\nКвадратичная форма равна %.5g\n", scalar(v, u));

}// End main

/* Умножение матрицы на вектор */

void matrix(float a[ ][4], float x[ ], float y[ ]){

int i, j;

for(i=0; i<4; i++){

for(y[ i ]=j=0; j<4; j++){

y[ i ] += a[ i ][ j ]*x[ j ];

}

}

}// End matrix

/* Скалярное произведение векторов */

float scalar(float x[ ], float y[ ]){

int i;

float z;

for(z=i=0; i<4; i++){

z+=x[ i ]*y[ i ];

}

return z;

}// End scalar

Замечание. Приведенный пример решает поставленную задачу только для размера матрицы 4х4, что не позволяет использовать данное решение для матриц других размеров. Это резко снижает область его применения (свойство массовости алгоритма). Для повышения универсальности алгоритма при использовании массивов в языке C применяют стандартный прием: объявляют массив максимально ожидаемого размера (проигрывая в памяти), затем задают реальные его размеры, контролируя непревышение выделенной памяти. Ниже приводится решение для максимального размера матрицы 30х30.

Пример. Вычислить: z=uТbu, где {ui]}, i=1...m; {bij]}, i,j=1...m.

/* Вычисление квадратичной формы */

int main( ){

float u[30], // Входной вектор

b[30][30], //Входная матрица

v[30], // Вектор b*u

scalar(int, float [ ], float [ ]);// Скалярное произведение векторов

int i, j,

m; // Размер матрицы

bool fl; // true-неправильный ввод

/* Умножение матрицы на вектор */

void matrix(int, float [ ][30], float [ ], float [ ]);

fl=true;

while(fl){

clrscr( );

printf("Размер матрицы:"); scanf("%d",&m);

if(m<1||m>30){

printf("Размер матрицы должен быть в диапазоне [1:%d]\n",30);

getch();

}else fl=false;

}

printf("Исходный вектор:\n");

for(i=0; i<m; i++){

scanf("%f", &u[ i ]);

}

printf("Исходная матрица:\n");

for(i=0; i<m; i++){

for(j=0; j<m; j++){

scanf("%f", &b[ i ][ j ]);

}

}

matrix(m, b, u, v);

printf("\n\n\nКвадратичная форма равна %.5g\n", scalar(m, v, u));

getch( );

}// End main

/* Умножение матрицы на вектор */

void matrix(int m, float a[ ][30], float x[ ], float y[ ]){

int i, j;

for(i=0; i<m; i++){

for(y[ i ]=j=0; j<m; j++){

y[ i ] += a[ i ][ j ]*x[ j ];

}

}

}// End matrix

/* Скалярное произведение векторов */

float scalar(int m, float x[ ], float y[ ]){

int i;

float z;

for(z=i=0; i<m; i++){

z+=x[ i ]*y[ i ];

}

return z;

}// End scalar

Аналогичный прием можно применять и в программировании на языке Basic, однако там имеется возможность при задании размеров выделять память под массивы в соответствии с ними.

Basic

В заголовке вызываемой процедуры для параметра-массива следует использовать ключевое слово ByRef. При этом копирования всего массива в локальную память процедуры не происходит и изменение его содержания приводит к изменению соответствующего аргумента в вызывающей процедуре.

Пример. Реализация предыдущей задачи. Только модуль Main.

Imports System.Console

Module Main

‘ Вычисление квадратичной формы

Sub main( )

Dim i, j, m As Short ‘ Размер матрицы

Dim fl As Boolean ‘ true-неправильный ввод

fl=True

Do While fl

Clear( )

Write("Размер матрицы:") : m=ReadLine( )

If m<1

WriteLine("Размер матрицы должен быть > 0”)

ReadLine( )

Else

fl=False

End If

Loop

‘Объявление массивов

Dim u(m-1) As Single ‘ Входной вектор

Dim b(m-1,m-1) As Single ‘ Входная матрица

Dim v(m-1) As Single ‘ Вектор b*u

WriteLine("Исходный вектор (вводить столбиком)")

For i=0 To m-1

u( i )=ReadLine( )

Next

WriteLine("Исходная матрица (вводить столбиком)")

For i=0 To m-1

For j=0 To m-1

b( i, j)= ReadLine( )

Next j

Next i

matrix(m, b, u, v)

WriteLine( )

WriteLine("Квадратичная форма равна {0:g5}", scalar(m, v, u))

ReadLine( )

End Sub