Передача массива в функцию

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

· адрес массива,

· размер массива.

Исключение составляют функции обработки строк, в которые достаточно передать только адрес.

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

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

Пример Дан массив из 10 элементов. Поменять местами наибольший и начальный элементы массива. Для операций поиска максимального элемента и обмена использовать функцию.

#include <stdio.h>

// Функция обмена

void change(int *x, int n)

{
// x - указатель на массив (адрес массива)

// n - размер массива

int i;

int max, index;

max = x[0];

index = 0;

// Поиск максимального элемента

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

{

if(x[i]>max)

{

max= x[i];

index = i;

}

}
// Обмен

x[index] = x[0];

x[0] = max;
}
int main()

{

int a[10];

int i;

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

{

printf("a[%d] = ", i);

scanf("%d", &a[i]);

}

change(a,10); // вызов функции обмена

// Вывод элементов массива

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

{

printf("%d ", a[i]);

}

getchar();

getchar();

return 0;
}

Результат выполнения

Пример Дан массив размерности n. Вычислить произведение четных элементов

#include <stdio.h>
int func(int *x, int n)

{ // произведение четных элементов

int p=1; // начальное значение произведения

int i;

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

{

if(x[i] % 2==0) // остаток от деления на 2 равен 0?

p = p * x[i];

}

return p;
}
int main()

{

int a[5]; // объявленмассив a из 5 элементов

int i;

int pr;

// Ввод элементов массива

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

{

printf("a[%d] = ", i);

scanf("%d", &a[i]); // &a[i] - адрес i-го элемента массива

}

pr = func(a, 5); // вычисление произведения

printf("\n pr = %d", pr); // вывод произведения четных элементов

getchar();

getchar();

return 0;
}

Функции обработки строк в Cи

В программе строки могут определяться следующим образом:

· как строковые константы;

· как массивы символов;

· через указатель на символьный тип;

· как массивы строк.

Кроме того, должно быть предусмотрено выделение памяти для хранения строки.

Любая последовательность символов, заключенная в двойные кавычки "", рассматривается как строковая константа. Для корректного вывода любая строка должна заканчиваться нуль-символом '\0'=0. При объявлении строковой константы нуль-символ добавляется к ней автоматически. Так, последовательность символов, представляющая собой строковую константу, будет размещена в оперативной памяти компьютера, включая нулевой байт.

Под хранение строки выделяются последовательно идущие ячейки оперативной памяти. Таким образом, строка представляет собой массив символов. Для хранения кода каждого символа строки отводится 1 байт.

Для помещения в строковую константу некоторых служебных символов используются символьные комбинации. Так, если необходимо включить в строку символ двойной кавычки, ему должен предшествовать символ "обратный слеш": '\"'.
Строковые константы размещаются в статической памяти. Начальный адрес последовательности символов в двойных кавычках трактуется как адрес строки. Строковые константы часто используются для осуществления диалога с пользователем в таких функциях, как printf().

При определении массива символов необходимо сообщить компилятору требуемый размер памяти.

char m[82];

Компилятор также может самостоятельно определить размер массива символов, если инициализация массива задана при объявлении строковой константой:

char m2[]="Горные вершины спят во тьме ночной.";
char m3[]={'Т','и','х','и','е',' ','д','о','л','и','н','ы',' ','п','о','л','н','ы',' ','с','в','е','ж','е','й',' ','м','г','л','о','й','\0'};

В этом случае имена m2 и m3 являются указателями на первые элементы массивов:

m2 эквивалентно &m2[0]
m2[0] эквивалентно 'Г'
m2[1] эквивалентно 'o'
m3 эквивалентно &m3[0]
m3[2] эквивалентно 'x'

При объявлении массива символов и инициализации его строковой константой можно явно указать размер массива, но указанный размер массива должен быть больше, чем размер инициализирующей строковой константы:

char m2[80]="Горные вершины спят во тьме ночной";

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

char *m4;

В этом случае объявление массива переменной m4 может быть присвоен адрес массива:

m4 = m3;
*m4 эквивалентно m3[0]='Т'
*(m4+1) эквивалентно m3[1]='и'

Следует отметить, что m3 является константой-указателем. Нельзя изменить m3, так как это означало бы изменение положения (адреса) массива в памяти, в отличие от m4.

Для указателя можно использовать операцию увеличения (перемещения на следующий символ):

m4++;

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

char *poet[4] = {"Погиб поэт!", "- невольник чести -",
"Пал," , "оклеветанный молвой..."};

В этом случае poet является массивом, состоящим из четырех указателей на символьные строки. Каждая строка символов представляет собой символьный массив, поэтому имеется четыре указателя на массивы. Указатель poet[0] ссылается на первую строк:

*poet[0] эквивалентно 'П',
*poet[l] эквивалентно '-',

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

char poet[4][23];

Разница заключается в том, что такая форма задает «прямоугольный»
массив, в котором все строки имеют одинаковую длину.


Описание

сhar *poet[4];

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

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

· выделить блок оперативной памяти под массив;

· проинициализировать строку.

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

char *name;
name = (char*)malloc(10);
scanf("%9s", name);

Для ввода строки использована функция scanf(), причем введенная строка не может превышать 9 символов. Последний символ будет содержать '\0'.

 

Функции ввода строк

Для ввода строки может использоваться функция scanf(). Однако функция scanf() предназначена скорее для получения слова, а не строки. Если применять формат "%s" для ввода, строка вводится до (но не включая) следующего пустого символа, которым может быть пробел, табуляция или перевод строки.

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

char * gets(char *);

В качестве аргумента функции передается указатель на строку, в которую осуществляется ввод. Функция просит пользователя ввести строку, которую она помещает в массив, пока пользователь не нажмет Enter.

 

Функции вывода строк

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

printf("%s", str); // str - указатель на строку или в сокращенном формате

printf(str);

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

int puts (char *s);

которая печатает строку s и переводит курсор на новую строку (в отличие от printf()). Функция puts() также может использоваться для вывода строковых констант, заключенных в кавычки.

 

Функция ввода символов

Для ввода символов может использоваться функция

char getchar();

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

 

Функция вывода символов

Для вывода символов может использоваться функция

char putchar(char);

которая возвращает значение выводимого символа и выводит на экран символ, переданный в качестве аргумента.

Пример Посчитать количество введенных символов во введенной строке.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()

{

char s[80], sym;

int count, i;

system("chcp 1251");

system("cls");

printf("Введитестроку: ");

gets(s);

printf("Введитесимвол: ");

sym = getchar();

count = 0;

for(i=0; s[i]!='\0'; i++)

{

if(s[i]==sym)

count++;

}

printf("В строке\n");

puts(s); // Вывод строки

printf("символ ");

putchar(sym); // Вывод символа

printf(" встречается %d раз",count);

getchar(); getchar();

return 0;
}

Результат выполнения