Способы описания строк в программе




Описание функции

Форма описания функции:

тип имя (тип1 арг1, тип2 арг2,...) /*заголовок функции*/

{

описание 1; /*описание

... внутренних переменных,

описание M; массивов*/

 

оператор 1; /*выполняемая

... часть*/

оператор N;

}

Заголовок функции:

тип– это тип возвращаемого функцией значения (результата) через ее имя.

Определенный тип – int, float, char,...

Неопределенный тип – void

Если тип не указан, то по умолчанию – int.

main() à int main()

void main()

имя – это идентификатор для обозначения функции

типI аргI,...– описания аргументов функции

типI тип аргумента

аргI имя аргумента

Функция может не иметь аргументов: тип имя ()

Примеры:

float my_func1(int k, float c, float d, char q)

{

...

}

void ftc(float a[], float *ptk, int n, long s)

{

...

}

Нельзя написать:

float my_func1(int k, float c,d, char q)

{...}

Описание функции может быть записано до или после функции main(), но не внутри ее:

1. До main():

При этом ничего дополнительно не надо записывать, т. к. компилятор сначала рассматривает f1(), а потом main().

2. Функция – после main()

void f1(int, float, chat, float *); /*прототип функции*/

 

void main()

{

/*прототип функции можно поместить здесь*/

...

вызов f1(...);

...

}

 

/*описание функции f1*/

void f1(int k, float x, char p, float *ptm)

{

...

}

 

Вызов функции

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

1. Функция имеет тип void. Вызов является самостоятельным оператором:

имя (факт_арг1,факт_арг2,...);

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

float z=1.5;

float *pts;

f1(20,z,’A’,&z);

f1(30,*pts,’N’,pts);

2. Функция имеет определенный тип (не void). Вызов не является самостоятельным оператором. Он записывается внутри другого оператора (присваивания, if, printf,...):

u=имя(факт_арг1,факт_арг2,...);

if(имя(факт_арг1,факт_арг2,...)...){...}

float fsum(float a, float b)

{

return a+b;

}

/*Вызов float fsum:*/

float x=5.5,y=7.1,z;

z=fsum(x,y); /* z==12.6 */

 

Варианты описания и использования функций

1. Функция возвращает результат через свое имя.

В описании функции указывается определенный тип возвращаемого функцией значения – int, float, double, char,... Внутри функции должен быть оператор return(a), где а –выражение для вычисления значения результата.

Вызов функции не является самостоятельным оператором. Он записывается внутри другого оператора (присваивания, if, printf,...).

Пример: вычислить функцию z=f(x,a,y)

для исходных данных: 1) x=5.3; a=-2.1

2) x=3.7; a=7.6

 

#include<stdio.h>

#include<math.h>

#include<conio.h>

/*Описание функции fz */

float fz(float x, float a)

{

float y;

y=1.7*log(fabs(x+2.5*a));

if(a>=x) return(a*exp(y*sin(2*x)));

else return(2.9*cos(a*y));

}

/*Главная функция main() */

void main()

{

float d,h;

d=fz(5.3,-2.1);

h=fz(3.7, 7.6);

printf(“x=5.3, a=-2.1, d=%3f\n”,d);

printf(“x=3.7, a= 7.6, h=%3f\n”,h);

printf(“fz(6.5,-3.4)=%3f\n”,fz(6.5,-3.4));

}

 

2. Функция возвращает одно или несколько значений через аргументы

В описании функции указывается тип – void (неопределенный). Аргументы, через которые будут возвращаться результаты, описываются как указатели:

void fun(int k, float *ptf, float z)

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

float f;

fun(20, &f, 5.25);

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

Если мы напишем:

void f(int arg1, int arg2, int arg3)

{

arg3=arg1+arg2;

}

то фактически выполнится следующая операция:

Копия_arg3 = Копия_arg1+Копия_arg2;

и значение arg3 не изменится.

Если же запишем следующим образом:

void f(int arg1, int arg2, int *arg3)

{

*arg3=arg1+arg2;

}

То будет выполнена запись суммы по адресу, заданному в копии параметра *arg3:

В результате значение суммы аргументов arg1 и arg2 будет вычислено правильно и сохранено в памяти.

Пример:

Составить функцию, которая меняет местами значения аргументов X и Y

#include<stdio.h>

#include<conio.h>

/* Функция без указателей */

void obmen1(float x, float y)

{

float tmp;

tmp=x;

x=y;

y=tmp;

}

/* Функция с указателями */

void obmen2(float *ptx, float *pty)

{

float tmp;

tmp=*ptx;

*ptx =* pty;

*pty=tmp;

}

/* Главная функция */

void main()

{

float g=7.5, h=11.2;

obmen1(g, h);

printf(“Ф-ция без указателей\ng=%.1f h=%.1f\n”,g, h);

obmen2(&g,&h);

printf(“Ф-ция c указателями\n g=%.1f h=%.1f\n”,g, h);

}

На экране получим:

Ф-ция без указателей

g=7.5 h=11.2 Результат неправильный

Ф-ция с указателями

g=11.2 h=7.5 Результат правильный

 

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

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

1) как массив с неопределенным количеством элементов:

void fun(float a[], int n,…);

где n – количество элементов массива a.

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

2) как указатель на начало массива:

void fun(float *pta, int n,…);

где n – количество элементов массива.

Внутри функции элементы массива записываются через указатель: *(pta+i) à a[i]

Примечание: Возможен 3-й способ описания массива с указанием фиксированного количества элементов:

void fun(float a[10],…);

Этот способ имеет недостаток. Функция может работать только с массивами длиной 10 элементов.

Вызов функции. При вызове функции для 1 и 2 способов на первом месте указывается имя массива, на втором – количество элементов:

float z[40], t[200];

fun(z, 40,…);

fun(t, 200,…);

Пример. Заданы три массива f[8], g[12], h[15], элементы которых вычисляются по формулам:

f[i]=1.7*i*cos(2.5*i)

g[j]=2.9*j*cos(3.1*j)

h[l]=3.5*l*cos(5.4*l)

Для каждого массива вычислить: среднее значение его элементов (sf, sg, sh) и количество элементов, больших среднего значения (kf, kg, kh). В данной задаче целесообразно использовать функцию, которая будет выполнять следующие действия:

а) формирование массива Х из n элементов по формуле:

x[i]=a*i*cos(b*i), i=1..n

б) вычисление среднего значения sx:

в) подсчет Кх – количества xi>sx

 

Текст программы для 3-го варианта:

#include<stdio.h>

#include<math.h>

#include<conio.h>

/* Описание функции */

void fmas(float x[], int n, float a, float b, float *pt_sx, int *pt_kx)

{

int i, kx=0;

float sx=0;

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

{

x[i]=a*i*cos(b*i);

printf(%.3f “,x[i]);

sx+=x[i];

}

printf(“\n”);

sx/=n;

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

if(x[i]>sx) kx++;

*pt_sx=sx;

*pt_kx=kx;

}

/* Главная функция */

void main()

{

float f[8], g[12], h[15], sf, sg, sh;

int kf, kg, kh;

clrscr();

printf(“Массив F из 8 элементов\n”);

fmas(f, 8, 1.7, 2.5, &sf, &kf);

printf(“sf=%.3f kf=%d\n”,sf,kf);

printf(“Массив G из 12 элементов\n”);

fmas(g, 12, 2.9, 3.1, &sg, &kg);

printf(“sg=%.3f kg=%d\n”,sg,kg);

printf(“Массив H из 15 элементов\n”);

fmas(h, 15, 3.5, 5.4, &sh, &kh);

printf(“sh=%.3f kh=%d\n”,sh,kh);

}

 

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

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

1) как массив с заданным количеством строк и столбцов

void fun(float c[5][10],…)

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

Недостаток этого способа – функция может работать только с матрицами 5*10

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

void fun(float c[][10], int m,…)

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

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

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

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

3) как указатель на начало массива:

void fun(float *ptc, int m, int n,…)

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

n – количество столбцов

Элементы массива: *(ptc+i*n+j) à c[i][j]

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

Вызов функции. При вызове функции первым аргументом указывают имя массива для 1-3 способов, а далее – другие аргументы в зависимости от способа:

1) float d[5][10], v[5][10];

fun (d,…); fun(v,…);

2) float a[7][10], b[12][10];

fun(a, 7,…); fun(b, 12,…);

3) float s[4][6], u[9][7];

fun(s, 4, 6,…); fun(u, 9, 7,…);

 

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

a[i,j]=1.9ij2-3.7i2j

b[k,l]=2.5kl2-4.1k2l

c[i,j]=5.3ij2+3.1i2j

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

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

1) формировать матрицу X[M,N] по формуле:

X[i,j]=fij2+gi2j

2) определять Хmax и его индексы imax, jmax

 

3) a) вычислять сумму элементов строки imax

б) вычислять произведение элементов столбца jmax

 

Программа примера для 4-го варианта:

#include<stdio.h>

#include<conio.h>

/* Описание функции fmatr */

void fmatr(float *ptx, int m, int n, float f, float g, float *pt_sx, float *pt_px, char name)

{

int i,j,imax,jmax;

float xmax,sx,px;

printf(“Матрица %c размером %dx%d\n”,name,m,n);

for(i=0;i<=m-1;i++)

{

for(j=0;j<=n-1;j++)

{

*(ptx+i*n+j)=f*i*j*j+g*i*i*j;

printf(“%.1f “, *(ptx+i*n+j));

}

printf(“\n”);

}

imax=jmax=0;

xmax=*ptx;

for(i=0;i<=m-1;i++)

for(j=0;j<=n-1;j++)

if(*(ptx+i*n+j)>xmax)

{

xmax=*(ptx+i*n+j);

imax=i;

jmax=j;

}

printf(“%cmax=%.1f imax=%d jmax=%d\m”, name, xmax, imax, jmax);

sx=0;

for(j=0;j<=n-1;j++)

sx+=*(ptx+imax*n+j);

px=1;

for(i=0;i<=m-1;i++)

p*=*(ptx+i*n+jmax);

*pt_sx=sx;

*pt_px=px;

}

/* Главная функция */

void main()

{

float a[3][4], b[5][6], c[4][7], sa, sb, sc, pa, pb, pc;

clrscr();

fmatr(a, 3, 4, 1.9, -3.7, &sa, &pa, ’A’);

printf(“sa=%.1f pa=%.1f\n”, sa, pa);

fmatr(b, 5, 6, 2.5, 4.1, &sb, &pb, ’B’);

printf(“sb=%.1f pb=%.1f\n”, sb, pb);

fmatr(c, 4, 7, 5.3, 3.1, &sc, &pc, ’C’);

printf(“sc=%.1f pc=%.1f\n”,sc,pc);

}

 

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

Описание функции. Такой аргумент описывается как указатель на функцию

void f1(тип (*fun)(тип1 арг1,…),…);

Внутри функции записывается вызов этой другой функции:

fun(x, y, z,…);

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

f1(f2,…)

где f2 – имя конкретной функции. Функция f2 должна иметь одинаковый список аргументов с функцией fun.

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

f1=1.1*x*sin(2.9x) для –5<=x<=5, Dx=0.2

f2=1.5ecos(1.8y) для 0<=y<=4, Dy=0.1

f3=3.7tg(4.2z) для 1<=z<=6, Dz=0.05

Обозначим: xmin=xn, xmax=xk, Dx=dx

Программа для 5-го варианта:

#include<stdio.h>

#include<math.h>

#include<conio.h>

/* Описание функций f1, f2, f3 */

float f1(float x)

{

return(1.1*x*sin(2.9*x));

}

float f2(float y)

{

return(1.5*exp(cos(1.8*y)));

}

float f3(float z)

{

return(3.7*tan(4.2*z));

}

/* Описание функции ff, которая вычисляет и выводит

значения любой из функций f1, f2, f3 */

void ff(float (*fun)(float x), float xn, float xk, float dx, char fname)

{

float x1,f;

printf(“Значения функции f%c для x Є[%.1f, %.1f] dx=%.2f\n”, fname, xn, xk, dx);

for(x1=xn; x1<=xk; x1+=dx)

{

f=fun(x1);

printf(“%.3f “,f);

}

printf(“\n”);

}

/* Главная функция */

void main()

{

clrscr();

ff(f1, -5, 5, 0.2, ’1’);

ff(f2, 0, 4, 0.1, ’2’);

ff(f3, 1, 6, 0.05, ’3’);

}

 

7. Работа со строками

В языке С есть тип данных char, который можно использовать как для работы с отдельными символами, так и со строками.

Символ один символ, заключенный в апострофы: 'A', '!', '+', занимает 1 байт памяти

Строка один и более символов, заключенных в кавычки "…". При записи в памяти, в конце строки автоматически записывается специальный символ конца строки '\0' – нуль-символ.

"А" – строка в памяти занимает 2 байта: 'A'+'\0'

"ABCDEF" ("ABCDEF\0")

"Results of calculations" В памяти: "Results of calculations\0"

 

Способы описания строк в программе

1. Строковая константа. Рассмотрена ранее. Используется в операторах ввода-вывода:

printf("Введите значение А=");

scanf("%f",&a);

2. Строка записывается в виде символьного массива:

char mst[50];

char a[30]=”Ошибка ввода данных”;

/* Ввод строки */

scanf(”%s”,mst); //Ввод с клавиатуры строки в массив mst

Со строкой можно работать в целом, используя ее имя – mst или посимвольно:

a[3]==’б’

a[5]==’a’

С символьным массивом можно работать только по одному символу:

char symb[7]={’a’,’b’,’c’,’d’,’e’,’f’,’g’};

symb[2]==’c’

symb= =&symb[0]

3. Строка записывается как указатель на тип char

char *pstr=”Memory size”;

pstr – имя строки

*(pstr+i) – i-й символ

*(pstr+4)==’r’

4. Массив символьных строк

char arr_str[5][40] ={“хлеб”,

”молоко”,

”кар т офель”,

”помидоры”,

”яблоки”};

arr_str[i] – имя i-й строки

arr_str[1] – имя строки "молоко"

arr_str[i][j] – j-й символ в i-й строке

arr_str[2][3]= =’т’

5. Массив указателей на тип char

char *pstr_arr[5]={“клубника”,

“вишня”,

“банан”,

“ананас”,

“слива” };

pstr_arr[i] – имя i-й строки

*(pstr_arr[i]+j) – j-й символ в i-й строке

*(pstr_arr[2]+2)==”н”

Здесь память для строк выделяется по их длине.

 

Ввод-вывод строк

1. Для ввода строк можно использовать следующие 2 функции:

- scanf(“%s”,имя_строки); - универсальная функция ввода

- gets(имя_строки); - специальная функция для

ввода строк с клавиатуры

Различие между scanf и gets состоит в том, что scanf вводит строку до 1-го пробела, в то время как gets вводит строку полностью, до нажатия клавиши ENTER.

Пример:

char fio[30];

scanf(%s”,fio);

gets(fio);

Вводим с клавиатуры:

Калашников И.П.ENTER

В результате работы функции scanf() в переменную fio запишется только фамилия (строка до первого пробела):

“Калашников”

В результате работы функции gets() в переменную fio запишется вся введенная с клавиатуры строка (до нажатия ENTER):

“Калашников И.П.”

2. Для вывода строк на экран можно использовать 2 функции:

- printf() c форматом %s

printf(“%s”,fio);

- puts(имя_строки);

puts(fio);

Эти функции выводят в строку полностью, но puts() всегда выводит курсор на начало следующей строки, а printf() переводит, если есть символ ‘\n’: “%s\n”.

 



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2016-02-16 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: