Опубликован: 02.02.2011 | Уровень: для всех | Доступ: платный
Лекция 17:

Структуры и указатели

< Лекция 16 || Лекция 17: 123 || Лекция 18 >

Операции над указателями на структуры

Эти операции не отличаются от операций над другими указателями на данные. Исключение составляет операция "стрелка" ( -> ). Если присвоить указателю на структуру конкретного структурного типа значение адреса одного из элементов массива структур того же типа, то, изменяя значение указателя (например, с помощью операций ++ или -- ), можно равномерно "перемещаться" по массиву структур.

Пример 2. Вычислить сумму заданного количества комплексных чисел, представленных в программе массивом структур.

#include "stdafx.h"
#include <iostream>
using namespace std;
#include <stdio.h>
struct complex {//Опредение структуры
                float x;
                float y;
               }array[]={1.0,2.0,3.0,-4.0,-5.0,-6.0,-7.0,-8.0};
  struct complex summa = {0.0, 0.0};
  struct complex *point = &array[0];

int _tmain(int argc, _TCHAR* argv[]) {
  int i;
  int k;
  k=sizeof(array)/sizeof(array[0]);
  for (i=0; i<k; i++){
    summa.x+=point->x;   
    summa.y+=point->y; }
  printf("\n Сумма: real=%f, \t  imag=%f", summa.x, summa.y);
  system("pause");
  return 0;
}

Пример 3. Программа считывает системное время компьютера и переводит его во время по Гринвичу.

#include "stdafx.h"
#include <iostream>
using namespace std;
#include <time.h>
int _tmain(int argc, _TCHAR* argv[]) {
  struct tm {
  int tm_sec;   //Секунды
  int tm_min;   //Минуты
  int tm_hour;  //Часы (0-23)
  int tm_mday;  //День месяца (1-31)
  int tm_mon;   //Месяц (0-11)
  int tm_year;  //Год (календарный год минус 1900)
  int tm_wday;  //День недели (0-6; Воскресенье = 0) 
  int tm_yday;  //День года (0-365)
  int tm_isdst; 
  //0, если переход на летнее время не используется
  };
  time_t t;
  struct tm *gmt, *area;
  t = time(NULL);
  //Преобразует дату и время в структуру
  area=localtime(&t); 
  printf("Секунды: %d\n", area->tm_sec);
  printf("Минуты: %d\n", area->tm_min);
  printf("Часы: %d\n", area->tm_hour);
  printf("День: %d\n", area->tm_mday);
  printf("Месяц: %d\n", area->tm_mon);
  printf("Год: %d\n", area->tm_year);
  printf("День недели: %d\n", area->tm_wday);
  printf("День года: %d\n", area->tm_yday);
  printf("Местное время: %s", asctime(area));
  //Преобразуем структуру в строку
  gmt=gmtime(&t);
  //Преобразует дату и время во время по Гривинчу
  printf("Время по Гринвичу: %s", asctime(gmt));
  system("pause");
  return 0;
}

Структуры и функции

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

Например:

//Определение структурного типа
struct person {
               char *name; 
               int age;
              };
  • Функция может возвращать структуру как результат:
    //Прототип функции
    struct person f (int N);
  • Функция может возвращать указатель на структуру:
    //Прототип функции
    struct person *ff (void);
  • Параметром функции может быть структура:
    //Прототип функции
    void fff (struct person str);
  • Параметром функции может быть указатель на объект структурного типа:
    //Прототип функции
    void ffff (struct person *pst);

При вызове функции fff() выделяется память для формального параметра, т.е. для вспомогательного объекта типа struct person. В этот объект переносится значение фактического параметра, заменяющего формальный параметр – структуру str. Далее выполняются действия, предусмотренные операторами тела функции fff(). Эти действия не могут изменять структуру, использованную в качестве фактического параметра.

В случае, когда параметром служит указатель на объект структурного типа, действиями внутри тела функции ffff() можно изменить ту структуру вызывающей функции, которая адресуется фактическим параметром pst.

Если функция не изменяет структуру, то такую структуру можно передать по значению.

Пример 4. Отображение полей структуры на экране.

#include "stdafx.h"
#include <iostream>
using namespace std;
  struct book {
    char title[40];
    char authors[30];
    char publishing_house[25];
    int year;
    int pages;
    };
void show_book(book b) { 
  cout << "Название: "<< b.title<<"\n";
  cout << "Автор: "<< b.authors<<"\n";
  cout << "издательство: "<< b. publishing_house<<"\n";
  cout << "Год: "<< b.year<<"\n";
  cout << "Количество страниц: " << b.pages<<"\n";
}

int _tmain(int argc, _TCHAR* argv[]) {
  book a={"Программирование на языке Си", "Подбельский В.В.",
          "Финансы и статистика", 2004, 600};
  show_book(a);
  system("pause");
  return 0;
}

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

Пример 5. Параметр функцииуказатель на структуру.

#include "stdafx.h"
#include <iostream>
using namespace std;
  struct book {
    char title[40];
    char authors[30];
    char publishing_house[15];
    int year;
    int pages;
   };
void input_book(book *b){ //структура передается по указателю
  cout << "Название: ";
  cin >> b->title;
  cout << "Автор: ";
  cin >> b->authors;
  cout << "Издательство: ";
  cin >> b->publishing_house;
  cout << "Год: ";
  cin >> b->year;
  cout << "Количество страниц: ";
  cin >> b->pages;
}

int _tmain(int argc, _TCHAR* argv[]) {
  book a,*pa=&a;
  input_book(pa);
  system("pause");
  return 0;
}

Пример 6. Параметр функцииссылка на структуру.

#include "stdafx.h"
#include <iostream>
using namespace std;
  struct book {
    char title[40];
    char authors[30];
    char publishing_house[15];
    int year;
    int pages;
  };
void input_book(book &b) { //структура передается по ссылке
  cout << "Название: ";
  cin >> b.title;
  cout << "Автор: ";
  cin >> b.authors;
  cout << "Издательство: ";
  cin >> b.publishing_house;
  cout << "Год: ";
  cin >> b.year;
  cout << "Количество страниц: ";
  cin >> b.pages;
}

int _tmain(int argc, _TCHAR* argv[]) {
  book a;
  input_book(a);
  system("pause");
  return 0;
}

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

Пример 7. Функции g1, g2 и g3 возвращают структуру.

#include "stdafx.h"
#include <iostream>
using namespace std;

struct ss {
           int a; 
           float b; 
          };
ss g1(ss v){ //параметр - значение
  v.a=7; 
  v.b=8; 
  return v; 
}
ss g2(ss &v){ //параметр - ссылка
  v.a=v.b+7; 
  v.b=v.a+8; 
  return v; 
}
ss g3(const ss &v){ //параметр - константная ссылка
  ss q;
  q.a=v.b+7; 
  q.b=v.a+8; 
  return q;
}

int _tmain(int argc, _TCHAR* argv[]) {
  ss x1,y1={1,2};
  ss x2,y2={3,4};
  ss x3,y3={5,6};
  x1=g1(y1);
  cout << "x1=" << x1.a << "; " << x1.b << "\n";
  cout << "y1=" << y1.a << "; " << y1.b << "\n";
  y1=g1(y1);
  cout << "x1=" << x1.a << "; " << x1.b << "\n";
  cout << "y1=" << y1.a << "; " << y1.b << "\n";
  x2=g2(y2);
  cout << "x2=" << x2.a << "; " << x2.b << "\n";
  cout << "y2=" << y2.a << "; " << y2.b << "\n";
  x3=g3(y3);
  cout << "x3=" << x3.a << "; " << x3.b << "\n";
  cout << "y3=" << y3.a << "; " << y3.b << "\n";
  y3=g3(y3);
  cout << "x3=" << x3.a << "; " << x3.b << "\n";
  cout << "y3=" << y3.a << "; " << y3.b << "\n";
  system("pause");
  return 0;
}

Ключевые термины

Значение указателя на структуруадрес расположения элементов структуры.

Структура – это совокупность переменных, объединенных одним именем, предоставляющая общепринятый способ совместного хранения информации.

Структура как значение функции является результатом работы функции, возвращающей совокупность значений полей соответствующей структуры.

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

Указатель на структуру – это указатель на расположение элементов структуры в памяти.

Краткие итоги

  1. В языке С++ определены указатели на структуры.
  2. В качестве инициализирующего значения указателя на структуру применяется адрес определяемого структурного объекта.
  3. При определении структуры запрещено указание в качестве элемента самого себя.
  4. Элементом структуры может быть указатель на определяемую или другую структуру.
  5. Указатель на структуру обеспечивает доступ к ее элементам двумя способами: прямым и косвенным.
  6. Операции над указателями на структуры не отличаются от операций над другими указателями на данные. Исключение составляет операция "стрелка" ( -> ).
  7. Структура может использоваться как параметр и значение функции.
  8. Взаимодействие структуры и функции может быть организовано через указатель или ссылку.
< Лекция 16 || Лекция 17: 123 || Лекция 18 >
Денис Курбатов
Денис Курбатов
Владислав Нагорный
Владислав Нагорный

Подскажите, пожалуйста, планируете ли вы возобновление программ высшего образования? Если да, есть ли какие-то примерные сроки?

Спасибо!

Ольга Замятина
Ольга Замятина
Россия, Калиниград, РГУ им. И. Канта, 2009
Эдуард Санин
Эдуард Санин
Украина, Харьков, ХАИ