Передача структур функциям

Содержание

В этом разделе рассказывается о передаче структур и их членов функциям.

Передача членов структур функциям


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

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);
}