Листинг 21.8. Использование битовых полей



1: #include <iostream.h>

2: #include <string.h>

3:

4: enum STATUS { FullTime, PartTime };

5: enum GRADLEVEL { UnderGrad, Grad };

6: enum HOUSING { Dorm, OffCampus };

7: enum FOODPLAN { OneMeal, AllMeals, WeekEnds, NoMeals };

8:

9: class student

10: {

11: public:

12: student():

13: myStatus(FullTime),

14: myGradLevel(UnderGrad),

15: myHousing(Dorm),

16: myFoodPlan(NoMeals)

17: { }

18: ~student() { }

19: STATUS GetStatus();

20: void SetStatus(STATUS);

21: unsigned GetPlan() { return myFoodPlan; }

22:

23: private:

24: unsigned myStatus: 1;

25: unsigned myGradLevel: 1;

26: unsigned myHousing: 1;

27: unsigned myFoodPlan: 2;

28: };

29:

30: STATUS student::GetStatus()

31: {

32: if (myStatus)

33: return FullTime;

34: else

35: return PartTime;

36: }

37: void student::SetStatus(STATUS theStatus)

38: {

39: myStatus = theStatus;

40: }

41:

42:

43: int main()

44: {

45: student Jim;

46:

47: if (Jim.GetStatus()== PartTime)

48: cout << "Jim is part time" << endl;

49: else

50: cout << "Jim is full time" << endl;

51:

52: Jim.SetStatus(PartTime);

53:

54: if (Jim.GetStatus())

55: cout << "Jim is part time" << endl;

56: else

57: cout << "Jim is full time" << endl;

58:

59: cout << "Jim is on the " ;

60:

61: char Plan[80];

62: switch (Jim.GetPlan())

63: {

64: case OneMeal: strcpy(Plan, "One meal"); break;

65: case AllMeals: strcpy(Plan, "All meals"); break;

66: case WeekEnds: strcpy(Plan, "Weekend meals"); break;

67: case NoMeals: strcpy(Plan, "No Meals");break;

68: default : cout << "Something bad went wrong!\n"; break;

69: }

70: cout << Plan << " food plan. " << endl;

71: return 0;

72: }

 

Результат:

Jim is part time

Jim is full time

Jim is on the No Meals food plan.

 

Анализ: Строки 4—7 содержат определение нескольких перечислений. Они используются для определения значения битовых полей внутри класса student.

В строках 9—28 объявляется класс student. Несмотря на тривиальность, он интересен тем, что все его данные упакованы в пяти битах. Первый бит определяет, является ли данный студент представителем очной (full time) или заочной (part time) формы обучения. Второй — получил ли этот студент степень бакалавра (UnderGrad). Третий — проживает ли студент в общежитии. И последние два бита определяют, какой из четырех возможных вариантов питания в студенческой столовой выбран студентом.

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

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

Чтобы убедиться в этом, замените выполнение функции GetStatus() следующим кодом:

STATUS student::GetStatus()

{

return myStatus;

}

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

Обратите внимание на то, что строка 47 должна проверить статус студента (full time или part time), а затем вывести соответствующее сообщение. Попробуем выполнить то же самое по-другому:

cout << "Jim is " << Jim.GetStatus() << endl;

В результате выполнения этого выражения будет выведено следующее сообщение:

Jim is 0

Компилятор не сможет перевести константу перечисления PartTime в соответствующую строку текста.

В строке 62 программы определяется вариант питания студента и для каждого возможного значения соответствующее сообщение помещается в буфер, а затем выводится в строке 70. Опять-таки заметим, что конструкцию с оператором switch можно было бы написать следующим образом:

case 0: strcpy(Plan,"One meal"); break;

case 1: strcpy(Plan,"All meals"); break;

case 2: strcpy(Plan,"Weekend meals"); break;

case 3: strcpy(Plan,"NoMeals"); break;

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

 

 

Стиль программирования

 

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

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

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

Отступы

 

Отступ табуляции должен составлять четыре пробела. Убедитесь в том, что ваш редактор преобразует каждую табуляцию в четыре пробела.

 

Фигурные скобки

 

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

• пара фигурных скобок должна быть выровнена по вертикали;

• фигурные скобки первого уровня в определении или объявлении должны быть выровнены по левому полю. Все строки блока объявления или определения записываются с отступом. Все вложенные пары фигурных скобок должны быть выровнены по одной линии со строкой программы, за которой начинается этот блок;

• строки блока никогда не должны находиться на одной линии с фигурными скобками, обрамляющими этот блок, например:

if (condition==true)

{

j = k;

SomeFunction();

}

m++;

 

Длинные строки

 

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

В языке C++ функции часто оказываются более короткими, чем в С, но по- прежнему остается в силе старый добрый совет: старайтесь сохранять свои функции достаточно короткими, чтобы всю функцию можно было увидеть на экране.

 


Дата добавления: 2019-02-12; просмотров: 234; Мы поможем в написании вашей работы!

Поделиться с друзьями:






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