Аргументом функции является двумерный массив (матрица)

 

Описание функции. Такой аргумент можно описать 3-мя способами: 

1. Матрица объявляется с заданным количеством строк и столбцов void name_fun (float c [5][10],...)

Внутри функции элементы массива записываются конечно, как переменная с индексом - c[i][j].

При вызове функции указывается имя массива.

name_fun (a,...);

Недостаток этого способа - функция может работать только с матрицами заданного размера.

2. Матрица объявляется как массив с неопределенным количеством строк и заданным количеством столбцов 

void name_fun (float c [] [10], int m,...)

где: m - количество строк

Внутри функции элементы массива обозначаются c[i][j]

При вызове функции указывается имя массива и фактическое количество строк

name_fun (a, 4,...)

Достоинством является то, что функция может работать с матрицами, которые имеют различное количество строк, например: A [5] [10], B [8] [10], C [20] [10].

Недостаток - длина строки (второй параметр) фиксированная - 10.

3. Матрица объявляется как указатель на массив:

void name_fun (float * ptc, int m, int n,...)

где: m - количество строк; n - количество столбцов.

Доступ к элементам массива осуществляется с помощью выражения  

*(ptc + i*m + j).

При обращении к функции нужно указать фактический массив с помощью адреса нулевого элемента и его размеры:

name_fun (&a[0][0], 10,8,...).

Этот способ является универсальным, так как функция может работать с массивами любых размеров.

Пример 6.9. Задана матрица действительных чисел размером 4х4. Найти сумму элементов матрицы, значение которых не превышает среднего арифметического всей матрицы.

Выполнить формирования матрицы и все расчеты с помощью функций.

В главной программе вывести на экран элементы матрицы, обратиться к функции и вывести искомый результат.

Рассмотрим все три варианта описания матрицы при объявлении функции.

1.Матриця объявляется с заданным количеством строк и столбцов.

Текст программы:

void sum(float x[4][4],float *pt_sr)

{

int i,j;

float s=0, sr;

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

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

{

x[i][j]= 0.0001*rand();

s=s+ x[i][j];

}

sr=s/16;

 *pt_sr=0;

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

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

if (x[i][j] < sr) *pt_sr=*pt_sr+ x[i][j];

}

 

 void main()

 {

float a[4][4], ssr;

int i,j;

sum(a,&ssr );

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

{

printf("\n");

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

printf("%5.1f",a[i][j]);

}

printf("\n ssr= %6.2f \n",ssr);}

2. Матрица объявляется как массив с неопределенным количеством строк и заданным количеством столбцов.

Текст программы:

 void sum(float x[][4],int l,float *pt_sr)

{   

int i,j;

float s=0, sr;

for (i=0;i< l;i++)

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

{

x[i][j]= 0.0001*rand();

s=s+ x[i][j];

}

sr=s/ l*4;

 *pt_sr=0;

for (i=0;i< l;i++)

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

if (x[i][j] < sr) *pt_sr=*pt_sr+ x[i][j];

}

 

  void main()

 {

float a[6][4],ssr;

int i,j,m;

printf(“задайте количество строк и столбцов матрицы ”);

scanf(“%d”,&n);

sum(a,m,&ssr);

for (i=0;i< n;i++)

{

printf("\n");

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

printf("%5.1f",a[i][j]);

}

printf("\n ssr= %6.2f \n",ssr);

 }

3.Матрица объявляется как указатель на начало массива:

Текст программы:

void sum (float *ptx, int n,int m,float *pt_sr)

{   

int i,j;

float s=0, sr;

for (i=0;i< n;i++)

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

{

*(ptx+i*m+j)=0.0001*rand();

s=s+*(ptx+i*m+j)=

}

sr=s/ n*m;

 *pt_sr=0;

for (i=0;i< n;i++)

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

if (*(ptx+i*l+j)< sr) *pt_sr=*pt_sr+*(ptx+i*l+j)=

}

 

Void main()

 {

float a[6][8];

int i,j;

printf(“задайте размеры матрицы”);

scanf(“%d%d”,&k,&l);

sum (&a[0][0],k,l,&ssr);

for (i=0;i<k;i++)

{

  printf("\n");

  for (j=0;j<l;j++)

  printf("%5.1f",a[i][j]);

}

  printf("\n ssr= %6.2f \n",ssr);

}

 

Пример 6.10. Задана матрица A [5][4]. Определить сумму элементов строки и произведение элементов столбца, на пересечении которых находится максимальный элемент.

Использовать следующие функции:

- формирования матрицы;

- вывод на печать;

- нахождения номеров строки и столбца, на пересечении которых находится максимальный элемент;

- нахождения суммы.

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

  

 Текст программы

/*функция формирует матрицу, которая объявлена с помощью указателя*/

void form (float *ptx, int n,int l)

{ int i,j;

for (i=0;i<n;i++)

for (j=0;j<l;j++)

  *(ptx+i*l+j)= 0.001*rand();

 }

 

/*функция печатает матрицу, которая объявлена с помощью указателя */

void vuvod (float *ptx, int n,int l)

{

int i,j;

for (i=0;i<n;i++)

{

  printf("\n ");

for (j=0;j<l;j++)

printf("%6.2f ",*(ptx+i*l+j));

}

}

 

/*функция находит номера строки и столбца, на пересечении которых находится максимальный элемент. Матрица объявлена с помощью указателя. Результат возвращается через аргументы*/

void find_max

(float *ptx,int n,int l, int *nstr, int *nstb)

{

int i,j;

float max=-10000;

for (i=0;i<n;i++)

for (j=0;j<l;j++)

if (*(ptx+i*l+j)> max)

{ max =*(ptx+i*l+j);

*nstr =i; *nstb =j;

}

}

/*функция, с помощью которой находится сумма. Результат возвращается через имя функции*/

 

  float find_s (float * ptx, int l, int nstr)

{

int j;

float s =0;

for (j=0;j<l;j++)

s=s+ *(ptx+nstr*l+j);

return s;

}

/* функция, с помощью которой находится произведение.

Результат возвращается через имя функции */

 

  float find_pr (float *ptx, int n, int l, int nstb)

{

int i;

float pr=1;

for (i=0;i<n;i++)

pr=pr* *(ptx+i*l+nstb);

return pr;

}

 

/*основная функция*/

Void main()

{

float a[5][4],sum, prouz;

int k,m,nstr1,nstb1;

 

form (&a[0][0], 5,4);

vuvod (&a[0][0], 5,4);

find_max (&a[0][0], 5,4 ,&nstr1,&nstb1);

printf("nom_stroki=%d nom_stolbza= %d \n",nstr1,nstb1);

 

sum=find_s (&a[0][0], 4, nstr1);

printf("\n sum= %6.2f\n",sum);

 

prouz=find_pr (&a[0][0], 5,4, nstb1);  

printf("\n pr= %6.2f\n",prouz);

}

}

 

Пример 6.11. Заданы две матрицы A [5][4], B[8][5], элементы которых вычисляются по формулам:

a i,j=1.9ij2-3.7i2j

b k,l=2.5kl2-4.1k2l

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

Для формирования матриц можно использовать функцию, которая в формальном виде будет вычислять элементы матрицы согласно формуле

  x[i][j]=k1*i*j2-k2*i2 *j

Значения коэффициентов k1 и k2 должно передавать как аргументы функции.

Текст программы

/*функция, которая формирует матрицу*/

 

void form(float *ptx,int n,int l, float k1,float k2)

int i,j;

for (i=0;i<n;i++)

for (j=0;j<l;j++)

*(ptx+i*l+j)=k1*(i+1)*(j+1)*(j+1)+k2*(i+1)*(i+1)*(j+1);

 }

 

/*функция, которая печатает матрицу*/

void vuvod (float *ptx,int n,int l)

{

int i,j;

   for (i=0;i<n;i++)

   { printf("\n ");

for (j=0;j<l;j++)

printf("%6.2f ",*(ptx+i*l+j));

}

}

 

/*функция, находит строки, в которых нет положительных элементов, и удаляет их. Возвращает также количество строк, которые остались*/

 

void fun_yd(float *ptx, int n, int l, int *kst)

{

int i,j,r, k, kyd=0;

  for (i=n-1;i>=0;i--)

  {

      k=0;

    for (j=0;j<l;j++)

    if (*(ptx+i*l+j)<=0) k++;

if (k==l) { kyd++;

            for (r=i; r<n; r++)

            for (j=0;j<l;j++)

                *(ptx+r*l+j)=*(ptx+(r+1)*l+j);

            }

  }    

*kst=n-kyd;

}

 

/* основная функция */

 void main()

 {

float a[8][5],b[12][6];

int i,j,kk;

clrscr();

form(&a[0][0],5, 4, 1.9, -3.7);

printf("\n исходный массив А ");

vuvod (&a[0][0],5,4);

fun_yd(&a[0][0], 5, 4, &kk);

printf("\n kk=%d ",kk);

printf("\n результирующий массив А ");

vuvod (&a[0][0], kk, 4);

 getch();

 

form(&b[0][0],8,5,2.5,-4.1);

printf("\n исходный массив B ");

vuvod (&b[0][0],8,5);

 fun_yd(&b[0][0], 8, 5, &kk);

 printf("\n kk=%d ",kk);

printf("\n результирующий массив B ");

vuvod (&b[0][0], kk, 5);

 getch();

 }

 

5. Аргументом функции является другая функция

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

<тип1>< имя 1>(<тип2> (*<имя 2>) (<типы аргументов>)…)

де: тип1 – тип функции;

имя 1 – имя функции;

тип2 – тип функции, которая является аргументом;

* имя 2 – указатель на имя функции, которая является аргументом;

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

Например:

 void namefun (void *pfun (int, float, float)…)

Описание функции, которая является аргументом, выполняется обычным образом:

<тип>< имя >(<тип_арг1> <имя_ арг2>, …)

Например:

     float f1 (float x)

     {

....

     }

Таких функций может быть несколько.

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

     namefun (f1 (арг1, ар2,...))

де f1 – имя фактичной функции.

Пример:6.12  Задано две функции

f1=sin(x)+1.3*x на отрезке [-6, 4]

f2=2*cos(x)-3.5*x на отрезке [- 4, 5]

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

Текст программы:

/* описание функции, которая находит максимальное значение функции-аргумента */ 

 

void f_max(float (*ptf)(float), float xn, float xk, float dx,float *max, float *xxk)

{float x;

x=xn;

*max= ptf(x);*xxk=x;

do

{

x=x+dx;

if(ptf(x)>*max) {*max=ptf(x);*xxk=x;}

}

while (x<xk);

}

 

 

/* описание функции, которая является  фактическим аргументом*/ 

 

Float f1 (float x)

  {

return sin(x)+1.3*x;

  }

 

/*описание второй функции, которая является  фактическим аргументом */

 

Float f2 (float x)

  {

return 2*cos(x)-3.5*x;

  }

 

/*основная функция*/ 

Void main()

{

float max1,x1,max2,x2,

xn1=-6,xk1=4,dx1=0.1,

xn2=-4,xk2=5,dx2=0.1;

 

/*вызов функции для обработки первой функции-аргумента */

 

f_max(f1, xn1, xk1, dx1, &max1, &x1 );

printf("\n x1= %6.1f max1= %6.2f \n",x1, max1);

 

/* вызов функции для обработки второй функции-аргумента */

 

f_max(f2, xn2, xk2, dx2, &max2, &x2 );

printf("\n x2= %6.1f max2= %6.2f \n",x2, max2);

}

Контрольные вопросы

 

1. Что такое функция?

2. Из каких двух этапов состоит использования функции?

3. Как выглядит структура программы с использованием функции?

4. Как выглядит описание функции?

5. Как выполняется вызов функции?

6. Какие аргументы называются формальными, а какие фактическими, какие требования предъявляются к использованию формально-фактических аргументов?

7. Как выглядит описание функции, если результат возвращается через имя функции?

8. Как выглядит описание функции, если результат возвращается через аргументы функции? Как выполняется ее вызов?

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

10. Какие существуют варианты описания функции, если ее аргументом является одномерный массив? Как обозначается элемент массива? Как осуществляется вызов?

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

12. Какие существуют варианты описания функции, если ее аргументом является двумерный массив? Как обозначается элемент массива? Как осуществляется вызов?

13. Напишите программу, содержащую 2 функции. В первой формируются значения массива. Во второй находится сумма всех элементов матрицы. В основной программе вводится размер матрицы и выполняется печать. При передаче матрицы используйте указатель.

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



СИМВОЛЬНЫЕ СТРОКИ

Символьные строки хранят такую информацию, как имена файлов, названия книг, имена служащих и другие символьные сочетания. Большинство программ на Cи широко используют символьные строки. В Cи символьные строки хранятся в массиве типа char, который заканчивается символом NULL (или ASCII 0). Таким образом, строкой в Си называется последовательность из одного или нескольких символов, которые заканчиваются на “\0” –ноль-символом. В Си отсутствует специальный тип для объявления строк, и для этого используют стандартный тип символов – char.

По отношению к строкам можно сказать следующее.

Чтобы объявить символьную строку, необходимо объявить массив типа char, Чтобы присвоить символы символьной строке, надо просто присваивоить символы элементам массива символьных строк. Программы Cи используют символ NULL (ASCII 0), чтобы отметить последний символ строки. Cи позволяет программам инициализировать символьные строки при их объявлении. Программы могут передавать символьные строки в функцию, как и любой массив.

Символьные данные

Символьный тип (сhar) — простой тип данных, предназначенный для хранения одного символа. В языке Си размер типа равен одному байту. Каждому символу сопоставлено число от 0 до 255, которое называется ASCII-кодом символа. Так как char - порядковый тип, то к его значениям применимы следующие функции:

succ ()- возвращает следующий символ литерного множества;

pred() - возвращает предыдущий символ литерного множества;

ord ()- возвращает значение кода литеры;

chr ()- возвращает значение литеры по ее коду, является обратной по отношению к функции ord().

Например:

succ('0')='1'- символ, следующий за символом 0, равен символу 1;

pred('3')='2‘ - символ, предшествующий символу 3, равен 2;

chr(65)='A' - символ, соответствующий коду 65, равен А;

ord('A')=65 - код символа А равен 65.

 


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: