Передача массива в функцию
Обработку массивов удобно организовывать с помощью специальных функций. Для обработки массива в качестве аргументов функции необходимо передать
· адрес массива,
· размер массива.
Исключение составляют функции обработки строк, в которые достаточно передать только адрес.
При передаче переменные в качестве аргументов функции данные передаются как копии. Это означает, что если внутри функции произойдет изменение значения параметра, то это никак не повлияет на его значение внутри вызывающей функции.
Если в функцию передается адрес переменной (или адрес массива), то все операции, выполняемые в функции с данными, находящимися в пределах видимости указанного адреса, производятся над оригиналом данных, поэтому исходный массив (или значение переменной) может быть изменено вызываемой функцией.
Пример Дан массив из 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;
}
Результат выполнения