C_Kurs_Lekt / C_II_семестр / 11-3_ФУНКЦИИ_3
.pdfОсновы программирования. Функции часть3 |
1 |
ФУНКЦИИ
Передача массивов и строк в функции. Пример 1:
/* Примеры задания строк (массивов) и их передача в функции. Лысый Д.А. Приложение к лекции - функции, массивы и строки */
#include <stdio.h> #include <stdlib.h> #include <conio.h> #include <string.h>
void pech(char *,char [], int , char *[]); void main(){
int n;
/* char s[]; ошибка! необходимо указывать размер или инициализировать
|
char s0[]="3r4"; |
правильно |
|
|
|
||
|
char s0[]={'3','r','4','\0'}"; правильно */ |
|
|||||
|
char s[]={"Строка 1"}; /* массив символов - строка из 8 символов и |
||||||
|
|
|
'\0' - 9 байт */ |
|
|
||
|
char *ss="Указатель на char"; /* |
указатель на char с инициализацией */ |
|||||
/* |
char *s1={'1','2','3','4','\0'} |
ошибка! |
*/ |
||||
/* |
char *s1="1234667"; |
/* указатель на char с инициализацией */ |
|||||
/* char sss[20]; а после sss[20]= "присвоем строку"; - !!ошибка |
|||||||
/* |
т.к. sss – константный указатель, можно присваивать посимвольно. |
||||||
|
char * s3; |
|
/* |
указатель на char не инициализированный */ |
|||
|
char *sNxM[]={"Первая строка из набора", "Вторая строка из набора", |
||||||
|
"Третья строка из набора", "Последняя строка из набора"}; |
||||||
|
clrscr(); |
|
|
|
|
|
|
|
printf("s = ? "); |
|
|
|
|
|
|
|
scanf("%s",s); |
|
|
|
|
|
|
|
printf("s[] = %s\n",s); |
|
|
|
|
||
|
printf("*ss = %s\n\n",ss); |
|
|
|
|||
/* scanf("%s",s3); |
/ |
* |
ошибка - необходимо предварительно связать |
||||
|
|
|
|
|
указатель cо строкой или выделить память */ |
||
|
s3="37492420348280"; |
/* или адрес строки |
*/ |
|
|||
|
s3=(char *) malloc(40); /* выделение памяти |
*/ |
|||||
|
printf("s3 = ? "); |
|
|
|
|
|
|
|
scanf("%39s",s3); |
/* |
|
теперь правильно |
*/ |
|
|
|
printf("s3 = %s |
Len(%s) = %d\n",s3,s3, strlen(s3)); |
n=sizeof(sNxM)/sizeof(sNxM[0]); /* вычисление числа элементов массива */ pech( s, ss, n, sNxM);
free(s3);
getch();
}
void pech(char *str1,char str2[], int n, char *str3[] /* или char **srt3 */){
int |
i; |
printf("\nПечать из функции\ns[] = %s\n",str1); |
|
printf("*ss = %s\n",str2); |
|
for |
(i=0;i<n;i++) printf("sNxM[%d] = %s\n",i,str3[i]); |
}
Результаты выполнения программы: s = ? String
s[] = String
*ss = Указатель на char
s3 |
= ? String3 |
|
|
|
s3 |
= String3 |
Len(String3) = 7 |
||
Печать из |
функции |
|
||
s[] = String |
|
|
||
*ss = Указатель на char |
|
|||
sNxM[0] = |
Первая строка из |
набора |
||
sNxM[1] = |
Вторая строка из |
набора |
||
sNxM[2] = |
Третья строка из |
набора |
||
sNxM[3] = |
Последняя строка |
из набора |
Пример 2:
/* Пример передачи в функции одномерных массивов func_1.c
Лысый Д.А. Приложение к лекции - передача строк и массивов в функции */ #include <stdio.h>
Основы программирования. Функции часть3 |
|
|
|
|
2 |
||
#include <conio.h> |
|
|
|
|
|
||
/* в списке формальных параметров массив-параметр |
можно описать как |
|
|||||
тип *имя или тип имя[] . Пример: |
double * mas == double mas[] . |
*/ |
|||||
void init_data(int , double *); |
|
|
|
|
|||
void pech(int , double []); |
|
|
|
|
|||
void main(){ |
|
|
|
|
|
|
|
int n=5; |
|
|
|
|
|
|
|
double mas[5]; |
/* статическое выделение памяти |
*/ |
|
||||
double |
*dmas; |
/* указатель |
для динамического выделение памяти */ |
|
|||
clrscr(); |
|
|
|
|
|
|
|
/* |
В функцию массивы всегда передаются через адрес начала массива. |
|
|||||
|
т.к. имя массива является константным указателем на начало (на нулевой |
||||||
|
элемент), то следующие записи эквивалентны: |
mas == &mas == &mas[0] */ |
|||||
init_data(n, mas); |
|
|
|
|
|
||
printf("Статический массив\n"); |
|
|
|
||||
pech(n, mas); |
|
|
|
|
|
|
|
printf(" N =?"); |
|
|
|
|
|
||
scanf("%d",&n); |
|
|
|
|
|
||
dmas=(double *)malloc(n*sizeof(double)); |
|
|
|||||
init_data(n, dmas); |
|
|
|
|
|
||
printf("Динамический массив\n"); |
|
|
|
||||
pech(n, dmas); |
|
|
|
|
|
|
|
getch(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
void init_data(int kol, double *mass){ |
|
|
|
||||
int i; |
|
|
|
|
|
|
|
for (i=0;i<kol;i++) mass[i]=rand(); |
|
|
|
||||
} |
|
|
|
|
|
|
|
void pech(int kol, double mass[]){ |
|
|
|
||||
int i; |
|
|
|
|
|
|
|
for (i=0;i<kol;i++) printf("%7.1lf ", mass[i]); |
|
|
|||||
printf("\n"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
Результаты выполнения программы: |
|
|
|
||||
Статический массив |
|
|
|
|
|
||
346.0 |
130.0 |
10982.0 |
1090.0 |
11656.0 |
|
|
|
N =?5 |
|
|
|
|
|
|
|
Динамический массив |
|
|
|
|
|
||
7117.0 |
17595.0 |
6415.0 |
22948.0 |
31126.0 |
|
|
|
|
|
|
|
|
Пример 3: |
|
|
/* |
Пример передачи в функции двумерных "статических" массивов. func_2.c |
||||||
|
Лысый Д.А. Приложение к лекции - передача строк и массивов в функции */ |
||||||
/* Директивы #define удобно использовать для определения |
|
||||||
максимальных значений индексов массивов. |
|
|
|||||
Препроцессор перед компиляцией заменит "MROW" на "5", а "MCOL" на "7". |
|
||||||
*/ |
|
|
|
|
|
|
|
#define MROW 5 |
|
|
|
|
|
|
|
#define MCOL 7 |
|
|
|
|
|
|
|
#include <stdio.h> |
|
|
|
|
|
||
#include <stdlib.h> |
|
|
|
|
|
||
#include <conio.h> |
|
|
|
|
|
||
void start_data(int, int, double [][MCOL]); |
|
|
|||||
void pech(int, int, double [][MCOL]); |
|
|
|
||||
void main(){ |
|
|
|
|
|
|
|
int n=5,m=7,l,i,j; |
|
|
|
|
|
||
/* "статическое" выделение памяти под массив - размер массива не изменяется |
*/ |
||||||
double mass[MROW][MCOL]; |
|
|
|
|
clrscr(); start_data(n, m, mass);
printf("Статический массив\n"); pech(n, m, mass);
getch();
}
void start_data(int row, int column, double m[][MCOL]){ int i,j;
int p;
for (i=0;i<row;i++)
for (j=0;j<column;j++)
Основы программирования. Функции часть3 |
|
|
|
3 |
||
m[i][j]=rand(); |
|
|
|
|
||
} |
|
|
|
|
|
|
void pech(int row, int column, double m[][MCOL]){ |
|
|||||
int i,j; |
|
|
|
|
|
|
for (i=0;i<row;i++){ |
|
|
|
|
||
for (j=0;j<column;j++) |
|
|
|
|
||
printf(" %7.1lf ", m[i][j]); |
|
|
|
|||
printf("\n"); |
|
|
|
|
|
|
} |
|
|
|
|
|
|
} |
|
|
|
|
|
|
Результаты выполнения программы: |
|
|
|
|||
Статический массив |
|
|
|
|
|
|
346.0 |
130.0 |
10982.0 |
1090.0 |
11656.0 |
7117.0 |
17595.0 |
6415.0 |
22948.0 |
31126.0 |
9004.0 |
14558.0 |
3571.0 |
22879.0 |
18492.0 |
1360.0 |
5412.0 |
26721.0 |
22463.0 |
25047.0 |
27119.0 |
31441.0 |
7190.0 |
13985.0 |
31214.0 |
27509.0 |
30252.0 |
26571.0 |
14779.0 |
19816.0 |
21681.0 |
19651.0 |
17995.0 |
23593.0 |
3734.0 |
Пример 4:
/* Пример передачи динамических двумерных массивов чисел в функции. func_4.c Лысый Д.А. Приложение к лекции - передача строк и массивов в функции */
#include <stdio.h> #include <stdlib.h> #include <conio.h>
void start_data(int, int, double **); void pech(int, int, double **);
void main(){ int n,m,i;
/* dmas - указатель на указатель (указатель на массив). */ double **dmas;
сlrscr();
printf(" N, M =? "); scanf("%d,%d",&n,&m);
/* выделяем память для массива указателей на double. */ dmas=(double **)malloc(n*sizeof(double *));
/* выделяем память для массивов-(строк матрицы) построчно и их начальные адреса запоминаем в массиве указателей. */
for (i=0; i<n;i++)
dmas[i]=(double *)calloc(m,sizeof(double)); start_data(n, m, dmas);
pech(n, m, dmas);
for (i=0; i<n;i++) free(dmas[i]); free(dmas);
getch();
}
void start_data(int row, int column, double **mass){ int i,j;
for (i=0;i<row;i++)
for (j=0;j<column;j++) mass[i][j]=rand();
}
void pech(int row, int column, double **mass){ int i,j;
for (i=0;i<row;i++){ for (j=0;j<column;j++)
printf(" %7.1lf ", mass[i][j]); printf("\n");
}
}
Результаты выполнения программы:
N, M =? 3,4
346.0 130.0 10982.0 1090.0
11656.0 7117.0 17595.0 6415.0
22948.0 31126.0 9004.0 14558.0
Пример 5:
/* Пример эмуляции и передачи динамических двумерных массивов чисел func_3.c в функции. (используя одномерные массивы)
Основы программирования. Функции часть3 |
4 |
|
|
Лысый Д.А. Приложение к лекции - передача строк и массивов в функции */ |
|
#include <stdio.h> |
|
|
#include <stdlib.h> |
|
|
#include <conio.h> |
|
|
void start_data(int, int, double []); |
|
|
void pech(int, int, double *); |
|
|
void main(){ |
|
|
|
int n,m,l,i,j; |
|
|
double *dmas; /* для динамического массива |
*/ |
|
clrscr(); |
|
/* |
dmas -указатель на одномерный динамический массив длиною |
|
|
MROW*MCOLUMS. Размер которого эквивалентен размеру двумерного |
|
|
массива из ROW строк и COLUMS столбцов. |
|
|
будем считать, что i текущая строка, а j текущий столбец, |
|
|
тогда элемент [i][j] двумерного массива будет находиться |
|
|
на z=i*COLUMS+j месте в одномерном массиве. |
|
|
Наоборот: элемент [z] одномерного массива будет находиться |
|
|
на z/COLUMS строке и z%COLUMS столбце. |
*/ |
|
printf(" N, M =? "); |
|
|
scanf("%d,%d",&n,&m); |
|
|
l=n*m; |
|
|
dmas=(double *)calloc(l,sizeof(double)); |
|
|
start_data(n, m, dmas); |
|
|
pech(n, m, dmas); |
|
printf("\nИндексы матрицы и их эквивалент в одномерном массиве\n"); for (i=0;i<n;i++){
for (j=0;j<m;j++)
printf(" [%d][%d] = [%2d] ", i,j,i*m+j); printf("\n");
}
printf("\nИндексы одномерного массива и их эквивалент в матрице\n"); for (i=0;i<l;i++) printf(" [%2d] = [%d][%d] ", i, i/m, i%m); printf("\n");
free( dmas); getch();
}
void start_data(int row, int column, double mass[]){ int i,j;
int p;
for (i=0;i<row;i++)
for (j=0;j<column;j++) mass[i*column+j]=rand();
}
void pech(int row, int column, double *mass){ int i,j;
for (i=0;i<row;i++){ for (j=0;j<column;j++)
printf(" %7.1lf ", mass[i*column+j]); printf("\n");
}
}
Результаты выполнения программы:
N, M =? 3,4
346.0 130.0 10982.0 1090.0
11656.0 7117.0 17595.0 6415.0
22948.0 31126.0 9004.0 14558.0
Индексы |
матрицы |
и их эквивалент в одномерном массиве |
|
|
|||
[0][0] |
= [ 0] |
[0][1] = [ 1] |
[0][2] = [ 2] |
[0][3] = [ 3] |
|||
[1][0] |
= [ 4] |
[1][1] = [ 5] |
[1][2] = [ 6] |
[1][3] |
= |
[ 7] |
|
[2][0] |
= [ 8] |
[2][1] = [ 9] |
[2][2] = [10] |
[2][3] |
= |
[11] |
|
Индексы |
одномерного массива и их |
эквивалент в |
матрице |
|
|
||
[ 0] = |
[0][0] |
[ 1] = [0][1] |
[ |
2] = [0][2] |
[ 3] = |
[0][3] [ 4] = [1][0] [ 5 |
|
= [1][1] [ 6] |
= [1][2] [ 7] |
= |
[1][3] [ 8] |
= [2][0] |
[ 9] = [2][1] [10] = [ |
||
][2] [11] = [2][3] |
|
|
|
|
|