В этом разделе рассказывается о передаче структур и их членов функциям.
При передаче функции члена структуры передается его значение, притом не играет роли то, что значение берется из члена структуры. Проанализируйте, например, следующую структуру:
struct fred { char x; int y; float z; char s[10]; } mike;
Например, обратите внимание, каким образом каждый член этой структуры передается функции:
func(mike.x); /* передается символьное значение x */ func2(mike.y); /* передается целое значение y */ func3(mike.z); /* передается значение с плавающей точкой z */ func4(mike.s); /* передается адрес строки s */ func(mike.s[2]); /* передается символьное значение s[2] */
В каждом из этих случаев функции передается значение определенного элемента, и здесь не имеет значения то, что этот элемент является частью какой-либо большей совокупности.
Если же нужно передать адрес отдельного члена структуры, то перед именем структуры должен находиться оператор &. Например, чтобы передать адреса членов структуры mike, можно написать следующее:
func(&mike.x); /* передается адрес символа x */ func2(&mike.y); /* передается адрес целого y */ func3(&mike.z); /* передается адрес члена z с плавающей точкой */ func4(mike.s); /* передается адрес строки s */ func(&mike.s[2]); /* передается адрес символа в s[2] */
Обратите внимание, что оператор & стоит непосредственно перед именем структуры, а не перед именем отдельного члена. И еще заметьте, что s уже обозначает адрес, поэтому & не требуется.
Когда в качестве аргумента функции используется структура, то для передачи целой структуры используется обычный способ вызова по значению. Это, конечно, означает, что любые изменения в содержимом параметра внутри функции не отразятся на той структуре, которая передана в качестве аргумента.
При использовании структуры в качестве аргумента надо помнить, что тип аргумента должен соответствовать типу параметра. Например, в следующей программе и аргумент arg, и параметр parm объявляются с одним и тем же типом структуры.
#include <stdio.h> /* Определение типа структуры. */ struct struct_type { int a, b; char ch; } ; void f1(struct struct_type parm); int main(void) { struct struct_type arg; arg.a = 1000; f1(arg); return 0; } void f1(struct struct_type parm) { printf("%d", parm.a); }
Как видно из этой программы, при объявлении параметров, являющихся структурами, объявление типа структуры должно быть глобальным, чтобы структурный тип можно было использовать во всей программе. Например, если бы struct_type был бы объявлен внутри main(), то этот тип не был бы виден в f1().
Как уже говорилось, при передаче структуры тип аргумента должен совпадать с типом параметра. Для аргумента и параметра недостаточно просто быть физически похожими; должны совпадать даже имена их типов. Например, следующая версия предыдущей программы неправильная и компилироваться не будет. Дело в том, что имя типа для аргумента, используемого при вызове функции f1(), отличается от имени типа ее параметра.
/* Эта программа неправильная и при компиляции будут обнаружены ошибки. */ #include <stdio.h> /* Определение типа структур. */ struct struct_type { int a, b; char ch; } ; /* Определение структуры, похожей на struct_type, но сдругими именами. */ struct struct_type2 { int a, b; char ch; } ; void f1(struct struct_type2 parm); int main(void) { struct struct_type arg; arg.a = 1000; f1(arg); /* несовпадение типов */ return 0; } void f1(struct struct_type2 parm) { printf("%d", parm.a); }