Помогни ни да направим Uroci.net по - богат! Добави урок

С++ част.2 (Типове данни)

C++ » C++
fix3d   трудност:    видян: 37894



22: The expense of spirit

Програмата вече е правилна. От гледна точка на стила на програмиране, обаче, тази програма все още не е съвършена. Операторът

st -= len + 1;

беше добавен с цел коригиране на грешката от директното увеличаване на st. Повторното даване на стойност на st не се вмества в логиката на програмата, като при това програмата е малко по-трудна за разбиране.

Разбира се, в програма като тази, наличието на един неясен оператор не изглежда особено опасно. Представете си, обаче, че тези оператори представляват 20% от изпълнимите оператори на програмата. Добавете, че програмата може да се състои от 10,000 реда и решаваният проблем не е тривиален. Част от програма, подобна на тази, често се нарича кръпка – нещо, добавено върху текста на съществуващата програма.

Ние закърпваме нашата програма за да коригираме логическа грешка в проекта й. По-добро решение е да се коригира недостатъка на първоначалния проект. Едно възможно решение е да се дефинира втори символен указател и да се инициализира със st. Например,

char *p = st;

А сега може да се използува при изчислението на дъължината на st, докато st остава непроменена.

while ( *p++ != ‘�’ )

Нека разгледаме и едно друго подобрение на нашата програма - то позволява работата ни да бъде използувана и от други програми. Според записаното до момента, няма начин друга програма да изчисли дължината на низ, освен ако не добави гореспоменатия текст. Тази алтернатива е особено разточителна. По-добрата алтернатива е да бъде обособена частта, изчисляваща дължината на низ и поставена в отделна функция. Тя вече може да бъде на разположение на всички програмисти, използващи системата. Ето една примерна дефиниция на функцията stringLength():

#include <stream.h>

void stringLength( char *st ) {
// calculate length of st_int len = 0;
char *p = st;
while ( *p++ ) ++len;
cout << len << ": " << st;
}

Дефиницията

char *p = st;

недостатъка на проекта на оригиналната програма. Операторът while ( *p++ )
представя кратък запис на следното:

while ( *p++ != ‘�’ )

Сега можем да променим програмата main() като използуваме новата функция:

extern void stringLength ( char* );
char *st = "The expense of spiritn";
main() {
stringLength( st );
return 0;
}

Функцията stringLength() е записана във файла string.C. Компилирането и изпълнението на тази програма може да бъде направено така:

$ CC main.C string.C
$ a.out

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

- Да проверим дали двата указателя адресират един и същ низ. Ако е така, низовете са еднакви.
- Иначе, да проверим дали дължините на двата низа са равни. Ако не са, двата низа не са еднакви.
- Иначе, да проверим дали символите на двата низа са еднакви. Ако е така, низовете са еднакви. Иначе, те не са еднакви. stringLength(), както е проектирана, не може да бъде използувана с тези нови функции. Един по-общ проект би следвало просто да предвиди връщането на дължината на низа. А каквото и да било извеждане на самия низ трябва да бъде оставено на програмата, извикваща stringLength(). Ето едно ново решение на проблема:

int stringLength( char *st ) {
// return length of st
int len = 0;
while ( *st++ )
++len;
}

Читателят може да бъде изненадан като види, че в тази версия на stringLength() отново st се увеличава директно. Това не представлява никакъв проблем при новата реализация поради следните две причини:

1. За разлика от по-ранните версии, тази реализация на функцията stringLength() не се нуждае от достъп до st след като st е била променяна, така че промените нямат значение.

2. Всички промени, извършени над стойността на st във stringLength() изчезват когато приключи изпълнението й. За st се казва, че е изпратена по стойност към функцията stringLength(). Това означава, фактически, че това, което stringLength() обработва е само копие на st. (Раздел 4.6 разглежда подробно обръщението по стойност).

stringLength() вече може да бъде викана от всяка програма, която иска да изчисли дължина на низ. За целите на програмата ни функцията main() би могла да бъде реализирана така:

...
main() {
int len = stringLength( st );
cout << len << ": " << st;
return 0;
}

stringLength() прави същото, което прави и библиотечната функция strlen(). Чрез включване на стандартния заглавен файл string.h програмистът може да използува голям брой полезни функции за обрабатка на низове, като например:

char *strcpy ( char *dst, char *scr );// копира scr в dst.
int strcmp ( char *s1, char *s2 );

// сравнява два низа. връща 0 ако са равни.

int strlen( char *st );// връща дължината на st.

За повече подробности и пълен списък на библиотечните функции, обработващи низове, направете справка в справочника на библиотеките.

Упражнение 1-5. Обяснете разликата между 0, ‘0’ и “0”.
Упражнение 1-6. Дадено е следното множество от дефиниции на променливи:

int *ip1, ip2;
char ch, *cp;

както и няколко оператара за присвояване, които са конфликт с описаните типове. Обяснете защо?

(a) ipl = "All happy families are alike";
(b) cp = 0; (c) cp = ‘�’;
(d) ip1 = 0; (e) ip1 = ‘�’;
(f) cp = &’a’; (g) cp = &ch;
(h) ip1 = ip2; (i) *ip1 = ip2;



Страници: «1 2 3 4 5 6 7 »

Сподели урока:



Коментари (1)

hotsaucebg на 27.06 2009 в 17:43ч.
Няма ли уроци само за C

Регистрирайте се, за да добавите коментар


Калдейта Ком ЕООД - © 2003-. Всички права запазени.
Препоръчваме: IT Новини