Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Использовать указатели при обработке текста.

Поиск

 

// Программа отлажена в Visual Studio 2008

#include "stdafx.h"

#include<conio.h>

#include<stdio.h>

#include <iostream>

using namespace std;

 

// Буква "e" или "E" входит 2 и более раз?

void two_raz(char *s, char ch1, char ch2)

{

int m; char *uk1,*uk2;

uk1 = s;

while(*uk1!='\0')

{

while(*uk1 == ' ')

uk1++;

 

uk2 = uk1; m = 0;

while (*uk1!= ' ' && *uk1!= '\0')

{

if(*uk1==ch1 || *uk1==ch2)

m++;

uk1++;

}

if(m>=2)

while(uk2<uk1)

{

putchar(*uk2);

uk2++;

}

putchar(' ');

}

}

 

 

//перевернуть слово на заданную букву

void revers(char *s, char ch)

{

char *uk1,*uk2, r;

while(*s)

{

// пропуск пробелов перед словом

while(*s==' ')

s++;

uk1=s; // указатель на начало слова

// пропуск слова

while(*s!= ' ' && *s!= '\0')

s++;

uk2=s-1; // указатель на конец слова

if(*uk1 == ch)

while(uk2 > uk1)

{

r=*uk2;

*uk2=*uk1;

*uk1=r;

uk1++;uk2--;

}

}

}

 

 

#define L 80

 

int main()

{

char poem[4][L]={

" Едва увидел я сей свет,",

" Уже зубами смерть скрежещет",

" Как моленией, косою блещет",

" И дни мои, как злак, сечет."

};

 

// а)

char bukwa_e = 'е', bukwa_E = 'Е';

for(int k=0; k<4; k++)

{

two_raz(poem[k], bukwa_e, bukwa_E);

putchar('\n');

}

 

// б)

char bukwa_c = 'с';

for(int k=0; k<4; k++)

{

revers(poem[k], bukwa_c);

puts(poem[k]);

}

getch();return 0;

}


СТРУКТУРЫ

 

Структура – пользовательский тип данных. Состоит, как и масив, из фиксированного числа компонентов, называемых элементами структуры (полями). Но в отличие от массивов, компоненты (поля) структуры могут быть различных типов и не могут непосредственно индексироваться. Каждое поле имеет уникальное имя, по которому на него ссылаются.

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

Примером структуры может служить анкета служащего, содержащая поля: табельный номер; фамилия, имя, отчество; часовая тарифная ставка; количество отработанных часов; оклад и др. Создание переменных структурного типа осуществляется в два этапа: сначала создается описание структурного типа (создание шаблона). Например, для приведенного выше примера это может выглядеть так:

 

struct anketa //Имя типа

{ char fio[30]; // фамилия

int tabn; // табельный номер

float tarif; // часовая тарифная сетка

int work; // отработано часов

float sum; // зарплата

};

 

Здесь anketa имя нового типа (т. н. дескриптор). При определении шаблона память не выделяется, реальных структур в памяти еще нет. Это имя типа используется в дальнейшем для создания конкретного объекта.

 

За именем типа идет заключенный в фигурные скобки список элементов структуры, с описанием типа каждого элемента (элементом структуры может быть переменная, массив или структура). Элементы структуры отделяются друг от друга точкой с запятой.

 

На втором шаге определяют переменные структурного типа:

[struct] anketa a0, a1, a2;

Это оператор выделяет место в памяти под три структуры типа anketa и дает им имена a0, a1, a2.

Дескриптор шаблона необходим, если описание структурного типа происходит в одном месте, а определение переменных структурного типа – в другом (т.е. как в приведенном выше примере). Обратите внимание на точку с запятой в конце шаблона. Дело в том, что в некоторых случаях описание структурного типа и определение структурных переменных можно объединить. В этом случае список переменных располагается в конце шаблона, как показано ниже. Здесь дескриптор можетотсутствовать.

 

 

struct

{ char fio[30];

int tabn;

float tarif;

int work;

float sum;

} a0, a1, a2;

Замечание. Существуют и другие способы определения структурного типа. Можно, в частности, использовать оператор переопределения типа:

typedef <спецификатор типа> <новое имя>;

С его помощью можно присвоить новое имя некоторому стандартному типу и изменить программу до неузнаваемости:

typedef float REAL;

REAL tarif, sum;

Определение структурного типа anketa с помощью оператора typedef может выглядеть так:

typedef struct

{ char fio[30];

int tabn;

REAL tarif;

int work;

REAL sum;

} anketa;

 

И тогда структурные переменные a0, a1, a2 определяются привычным способом:

anketa a0, a1, a2;

Начальная инициализация.

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

 

anketa a0={“Иванов А. П.”, 2345, 21.5, 100};

 

Доступ к полям структуры.

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

 

a1.sum = a1.tarif * a1.work;

strcpy (a1.fio, “Леонов Л.М.”);

cin.getline (a1.fio, 30);

 

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

 

К структурам одного типа как единому целому применима только операция присваивания, например

a2=a1;

Остальные действия со структурами (ввод-вывод, сравнение и др.) осуществляются поэлементно (над отдельными полями). При вводе элементы структуры вводятся последовательно по одному. Заполнять их можно в любом порядке.

 

Массивы структур

Одиночные структуры используются редко при обработке данных. Наиболее часто они выступают как компоненты массивов и записи файлов. При объявлении массива структур предварительно надо объявить саму структуру как новый тип данных.

Для обращения к полю в массиве структур также используют уточненное (составное) имя, но теперь надо указать в квадратных скобках еще номер (индекс) нужной структуры, например

 

anketa a[5];

a[0].tarif=15.75;

gets(a[0].fio);

scanf(“%d %f”, &a[0].work, &a[0].tarif);

 

Рассмотрим следующий пример.

Задача 160. Программа по запросу вводит до 30 записей, каждая из которых содержит фамилию служащего, его часовую тарифную ставку и количество отработаных часов, а затем вычисляет зарплату служащего, и выводит на экран ведомость на получение зарплаты.

 

#define LIM 30 // предельное число служащих

#include <string.h>

#include<conio.h>

#include<stdio.h>

#include <iostream>

using namespace std;

 

struct anketa //anketa - имя нового типа!

{ char fio[30];

int tabn;

float tarif;

int work;

float sum;

};

 

void main()

{ system("chcp 1251");

anketa vedom[LIM]; //массив структур типа anketa

int k=0,i;

cout<<"Введи до "<<LIM<<" фамилий"<<'\n';

cout<<"Для прекращения - Enter в начале строки"<<'\n';

cout<<"Фамилия "<<k+1<<" -го служащего";

while((gets(vedom[k].fio)!=NULL)&&

(vedom[k].fio[0])!='\0' && k<LIM)

{

cout<<"табельн номер - "<<vedom[k].fio; cin>>vedom[k].tabn;

cout<<"часовой тариф - "<<vedom[k].fio; cin>>vedom[k].tarif;

cout<<"отраб часов - "<<vedom[k].fio; cin>>vedom[k].work;

// начисление зарплаты

vedom[k].sum = vedom[k].tarif*vedom[k].work;

k++;

//ВНИМАНИЕ!!!

fflush(stdin); //очистить входной поток!

// Иначе 2-ю фамилию уже не введем, gets() определяет NULL

if(k<LIM)

cout<<"Фамилия "<<k+1<<" -го служащего ";

}

 

cout<<"\n\n\n\t\tВедомость на выплату зарплаты\n\n";

for(i=0; i<k; i++)

printf("\n%20s %10.2f %8d %10.2f",

vedom[i].fio,vedom[i].tarif,vedom[i].work, vedom[i].sum);

getch();

}

 

Указатели на структуры

Указатель на структуру мы можем определить таким же способом, как и указатель на значение любого другого типа. Например,

 

struct anketa *uk;

 

определяет указатель на структуру типа anketa. Этот указатель на структуру далее может быть исползован как обычно. Однако использование составных (квалифицируемых) имен в этом случае несколько меняется. Например, если имеют место определения

 

struct anketa a1;

uk = &a1;

 

то запись (*uk).tarif обеспечивает доступ к полю tarif структуры a1, на которую ссылается указатель uk. Скобки здесь необходимы, так как операция “точка” имеет более высокий приоритет, нежели '*'. Эта запись означает "мне нужно поле tarif той структуры, на которую ссылается указатель uk ".

 

В языке С/С++ есть, однако, более элегантная конструкция использования указателя для доступа к полям структуры, а именно, доступ к элементу структуры по указателю с помощью операции "–>" в виде: <указатель на структуру> "–>" <элемент_структуры>.

 

uk -> tarif

 

Обе формы использования указателя здесь равноправны и соответствуют записи a1.tarif. Использование ”стрелки”, т.е. пары символов (–>) делает использование указателей на структуры более выразительным.

Есть немало причин использования указателей на структуры. Одна из них – обеспечить двустороннюю связь с функциями. Например, для начисления заработной платы (sum) служащим по известной часовой тарифной ставке (tarif) и количеству отработанных часов (work) можно воспользоваться функцией summa4(), которая в качестве аргумента получает указатель (адрес) на структуру типа anketa, что обеспечивает двустороннюю передачу информации

 

// 4)возврат функцией результата через указатель

// прототип: void summa4(struct anketa *)

 

void summa4(struct anketa *uk)

{

uk->sum=(uk->tarif*uk->work);

}

 

Для вызова такой функции (в цикле с параметром k используется массив структур vedom[]) следует записать

 

summa4(&vedom[k]);

 

Обратите внимание, что имя структуры vedom[k]– не адрес её (!). Поэтому наличие символа & перед именем структуры необходимо.

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

 

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

 

// 3a) аргумент - ссылка на структуру.

 

void summa3a(anketa &nachisleno)

{

nachisleno.sum = (nachisleno.tarif*nachisleno.work);

}

 

Для вызова такой функции (в цикле с параметром k используется массив структур vedom[]) достаточно записать

 

// 3а)передача функции ссылки на структуру в качестве аргумента

summa3a(vedom[k]);

 



Поделиться:


Последнее изменение этой страницы: 2016-12-16; просмотров: 373; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.22.181.81 (0.006 с.)