Структуры и функции
Как и любой другой объект, структура может использоваться в качестве параметра функции и также может быть возвращаемым объектом функции.
Рассмотрим использование структур в функциях на примере:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <stdio.h>
struct time
{
int hour;
int minute;
int second;
};
// прототип функции
struct time addminutes(struct time, int);
int main(void)
{
struct time current_time = {17, 38, 10};
int minutes = 21;
struct time result_time = addminutes(current_time, minutes);
printf("%d:%d:%d \n", result_time.hour, result_time.minute, result_time.second);
result_time = addminutes(current_time, 23);
printf("%d:%d:%d \n", result_time.hour, result_time.minute, result_time.second);
result_time = addminutes(current_time, 382);
printf("%d:%d:%d \n", result_time.hour, result_time.minute, result_time.second);
return 0;
}
struct time addminutes(struct time t, int minutes)
{
struct time result ={t.hour, t.minute, t.second};
int h, d;
// прибавляем минуты
result.minute += minutes;
// если минут больше 59, делим на 60
if(result.minute >=60)
{
h = result.minute / 60;
// от минут вычитаем 60 * h
result.minute -= 60 * h;
// к часам прибавляем h
result.hour +=h;
}
// если часов больше 23, делим на 24
if(result.hour >=24)
{
d = result.hour / 24;
// от часов вычитаем d * 24
result.hour -= 24 * d;
}
return result;
}
В начале программы определена структура time, которая представляет время и содержит три элемента для хранения значений для часов, минут и секунд.
В конце программы определена функция addminutes(), прибавляет к дате некоторое количество минут. Первый параметр функции представляет структуру time, а второй - количество минут, которое надо прибавить. Возвращаемое значение функции также представляет структуру time. В самой функции с помощью некоторой простейшей логики создаем новый объект структуры time, присваиваем ему значения, переданные через первый параметр, и добавляем нужное количество минут.
Затем в функции main последовательно вызываем функцию addminutes, добавляя к некоторому времени разное количество минут.
Консольный вывод программы:
17:59:10
18:1:10
0:0:10
Указатели на структуру как параметры
При использовании структур в качестве параметров в функции следует учитывать, что при вызове функции для структуры, также как и для параметров типа int или char, выделяется память, в которую помещаются значения элементов структуры. То есть структура в функцию передается по значению, а это значит, что переданную в функцию структуру мы изменить не можем.
Для примера определим функцию, где попытаемся изменить структуру:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <stdio.h>
struct time
{
int hour;
int minute;
int second;
};
// прототип функции
void addminutes(struct time, int);
int main(void)
{
struct time current_time = {17, 38, 10};
addminutes(current_time, 21);
printf("In main \t %d:%d:%d \n", current_time.hour, current_time.minute, current_time.second);
return 0;
}
void addminutes(struct time t, int minutes)
{
int h, d;
// прибавляем минуты
t.minute += minutes;
// если минут больше 59, делим на 60
if(t.minute >=60)
{
h = t.minute / 60;
// от минут вычитаем 60 * h
t.minute -= 60 * h;
// к часам прибавляем h
t.hour +=h;
}
// если часов больше 23, делим на 24
if(t.hour >=24)
{
d = t.hour / 24;
// от часов вычитаем d * 24
t.hour -= 24 * d;
}
printf("In addminutes \t %d:%d:%d \n", t.hour, t.minute, t.second);
}
Если мы запустим программу, то увидим передаваемая структура current_time в функцию addminutes после выполнения этой функции не изменится:
In addminutes 17:59:10
In main 17:38:10
Если мы действительно хотим изменить структуру в функции, то на надо передавать не саму структуру, а указатель на нее:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <stdio.h>
struct time
{
int hour;
int minute;
int second;
};
// прототип функции
void addminutes(struct time *, int);
int main(void)
{
struct time current_time = {17, 38, 10};
struct time * p_time = ¤t_time;
addminutes(p_time, 21);
printf("In main \t %d:%d:%d \n", current_time.hour, current_time.minute, current_time.second);
return 0;
}
void addminutes(struct time *t, int minutes)
{
int h, d;
// прибавляем минуты
t->minute += minutes;
// если минут больше 59, делим на 60
if(t->minute >=60)
{
h = t->minute / 60;
// от минут вычитаем 60 * h
t->minute -= 60 * h;
// к часам прибавляем h
t->hour +=h;
}
// если часов больше 23, делим на 24
if(t->hour >=24)
{
d = t->hour / 24;
// от часов вычитаем d * 24
t->hour -= 24 * d;
}
printf("In addminutes \t %d:%d:%d \n", t->hour, t->minute, t->second);
}
Теперь в функцию передается указатель на структуру p_time, который содержит адрес структуры current_time. В итоге любое изменение значений по этому указателю приведет к изменению самой структуры current_time. И результаты программы будут уже отличаться:
In addminutes 17:59:10
In main 17:59:10
Указатели на структуру как результаты функций
И еще один вариант использования структур в функции - это возвращение из функции указателя на структуру. Например, определим функцию, которая будет возвращать указатель на структуру time:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <stdio.h>
#include <stdlib.h>
struct time
{
int hour;
int minute;
int second;
};
// прототип функции
struct time * input(void);
int main(void)
{
struct time * p_time = input();
printf("%d:%d:%d \n", p_time->hour, p_time->minute, p_time->second);
free(p_time); // освобождаем память
return 0;
}
struct time * input()
{
// выделяем память для структуры
struct time * p_time = (struct time *) malloc(sizeof(struct time));
// ввод значений
printf("Enter hour: ");
scanf("%d", &p_time->hour);
printf("Enter minutes: ");
scanf("%d", &p_time->minute);
printf("Enter seconds: ");
scanf("%d", &p_time->second);
return p_time;
}
В функции input вначале выделяем память для структуры, получая указатель на выделенный блок памяти.
Потом поочередно вводим значения для элементов структуры и возвращаем указатель из функции.
В функции main вызываем функцию input, получая из нее указаетель. Используя полученный указатель, можно получить значения элементов структуры. И в конце освобождаем выделенную под структуру динамическую память.
Консольный вывод программы:
Enter hour: 22
Enter minutes: 14
Enter seconds: 18
22:14:18