Опубликован: 14.12.2010 | Доступ: свободный | Студентов: 3128 / 726 | Оценка: 4.53 / 4.12 | Длительность: 26:28:00
Лекция 16:

Структуры и функции языка С

< Лекция 15 || Лекция 16: 1234 || Лекция 17 >
Аннотация: В лекции рассматриваются способы передачи структур в функции, научиться создавать функции, которые возвращают структуры и указатели на структуры.

Теоретическая часть

Разрешенными операциями над структурами являются копирование или присваивание структуры как целого, взятие ее адреса операцией &, а также обращение к ее элементам [15.1]. Копирование и присваивание включает в себя также передачу аргументов в функции и возвращение значений из функций.

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

struct fred 
{
char x;
int y;
float z;
char str[10]; // с учетом символа окончания строки
} mike;

Тогда каждый член этой структуры можно передать функции, например,

func(mike.x); // передается символьное значение х
func2(mike.y);// передается целое значение y
func3(mike.z);// передается значение с плавающей точкой z
func4(mike.str);// передается адрес строки str[10] 
func(mike.str[2]);// передается символьное значение str[2]

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

func(&mike.x); // передается адрес символа х
func2(&mike.y);// передается адрес целого y
func3(&mike.z);// передается адрес члена z с плавающей точкой
func4(mike.str);// передается адрес строки str 
func(&mike.str[2]);// передается адрес символа в str[2]

Когда в качестве аргумента функции используется структура, для передачи целой структуры используется обычный способ вызова по значению [15.2]. Это означает, что любые изменения в содержимом параметра внутри функции не отразятся на той структуре, которая передана в качестве аргумента.

При использовании структуры в качестве параметра надо помнить, что тип аргумента должен соответствовать типу параметра. В качестве примера рассмотрим следующий программный код [15.2]:

#include <stdio.h>
#include <conio.h>

// Определение глобального типа структуры
struct struct_type {
int a, b;
char ch;
};

// Прототип функции
void fun(struct struct_type parm);

int main (void) {
struct struct_type arg;

arg.a = 1000;
fun(arg);

printf("\n Press any key: ");
_getch();
return 0;
}

// Определение функции
void fun(struct struct_type parm)
{
printf("\n %d\n", parm.a);
}

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

Когда используется указатель на структуру, вместо оператора точки используется оператор "стрелка". Видоизменим рассмотренную программу, введем в нее указатель на структуру:

#include <stdio.h>
#include <conio.h>

// Определение глобального типа структуры
struct struct_type { int a, b; char ch; };

// Прототип функции
void fun(struct struct_type *parm);
int main (void)
 {
struct struct_type arg,*PTR;
PTR = &arg;

PTR->a = 999;
fun(PTR);
printf("\n Press any key: ");
_getch();
return 0;
}

// Определение функции
void fun(struct struct_type *parm)
{
printf("\n %d\n", parm->a);
}

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

#include <stdio.h>
#include <conio.h>

// Определение глобального типа структуры
struct struct_type {int a, b; char ch; };

// Прототип функции
void fun(struct struct_type STRUCT3);

int main (void) 
{
	struct struct_type struct2 = 	{2,	3,	'Z'	};
	
fun(struct2);

printf("\n Press any key: ");
_getch();
return 0; }
// Определение функции
void fun(struct struct_type STRUCT3)
 {
	printf("\n %c: %d + %d = %d\n", \
	STRUCT3.ch, STRUCT3.a, STRUCT3.b, STRUCT3.a + STRUCT3.b);
}

В современных версиях языка С, в том числе и ANSI C, структуры не только можно передавать функции в качестве аргументов, но и возвращать в качестве возвращаемого значения [15.3]. Использование структур в качестве аргументов функции позволяет передавать функции информацию о структуре. Использование функций для возврата структур позволяет передавать информацию из вызываемой функции в вызывающую функцию. Указатели на структуры допускают также двусторонний обмен данными.

Практическая часть

Пример 1. Напишите программу передачи частей структуры в качестве аргументов функции.

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

Программный код решения примера:

#include <stdio.h>
#include <conio.h>

#define MAX 20

// Шаблон структуры
struct test {char A[MAX+1]; double ax; char B[MAX+1];
double by;
};

//Прототип вспомогательной функции
double sum(double, double);

// Главная функция
int main (void) {
// Создание структурной переменной	
	struct test AB;

	//Заполнение полей структуры 
	printf("\n\t Type 1 st name: ");
	gets_s(AB.A, MAX);
	printf("\t Enter the first real number: ");
	scanf_s("%lf", &AB.ax);
	_flushall();
	printf("\n\t Enter 2 nd name: ");
	gets_s(AB.B, MAX);
	printf("\t Enter the second real number: ");
	scanf_s("%lf", &AB.by);

printf("\n\t The sum of two numbers \
%1.2f and %1.2f, %s and %s: %1.2f\n",
AB.ax, AB.by, AB.A, AB.B, sum(AB.ax, AB.by)); 

	printf("\n Press any key: ");
	_getch();
	return 0; }

// Функция суммирования двух чисел
double sum(double x, double y) {
return (x + y);
}

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

Сумма двух чисел, переданных в качестве аргументов функции

Рис. 15.1. Сумма двух чисел, переданных в качестве аргументов функции

Задание 1

  1. Одним из вводимого имени примите свое имя (имя пользователя).
  2. Предусмотрите предварительный подсчет суммы двух чисел по возвращаемому значению функции sum().
  3. Произведите инициализацию структуры в программе и передайте ее вещественные данные в функцию для подсчета их суммы.
  4. Напишите функцию, аргументом которой будет вычисленная сумма двух чисел – полей структуры, чтобы эта функция выполняла вывод на консоль полученной суммы.
  5. В программе операцию "точка" замените на операцию "стрелка".
< Лекция 15 || Лекция 16: 1234 || Лекция 17 >
Мухаммадюсуф Курбонов
Мухаммадюсуф Курбонов