|
Программирование >> Структурное программирование
Часто основой разработок являются доставшиеся в наследство программы, написанные на ранних версиях С, в которых спецификатор const не использовался, потому что его просто не было в наличии. По этой причине существуют огромные возможности для улучшения разработок программного обеспечения, написанного на старых версиях С. Хотя многие программисты, постоянно использующие С ANSI, все-таки не применяют в своих программах const, потому что они начинали программировать на ранних версиях С. Эти программисты упускают много возможностей по созданию хорошего программного обеспечения. Существует шесть возможностей использования (или не использования) const с параметрами функции - две с передачей параметров по значению и четыре с передачей параметров по ссылке. Как выбрать одну из этих возможностей? Давайте руководствоваться принципом наименьших привилегий. Всегда обеспечивайте функцию в ее параметрах достаточным доступом к данным, чтобы она могла выполнять свои задачи, но не более того. В главе 3 мы объясняли, что когда функция вызывается с использованием передачи параметров по значению, в вызове функции создается копия аргумента (или аргументов) и она передается функции. Если копия в функции модифицируется, исходное значение в вызывающем операторе остается без изменений. Во многих случаях значение, передаваемое функции, модифицируется для того, чтобы функция могла выполнить свою задачу. Однако, в некоторых отдельных случаях значение в вызываемой функции не должно изменяться даже несмотря на то, что она манипулирует копией исходного значения. Рассмотрим функцию, которая получает одномерный массив и его размер как аргументы и печатает этот массив. Такая функция должна циклически обрабатывать массив и выводить значения каждого его элемента. Размер массива используется в теле функции для определения верхнего индекса массива, при котором цикл должен завершаться, так как печать окончена. Размер массива не изменяется в теле функции. Замечание по технике программирования 5.2 Если значение не изменяется (или не должно изменяться) в теле функции, которой оно передается, параметр должен быть объявлен как const, чтобы иметь гарантию от неожиданных его изменений. В случае попытки изменить значение константного параметра компилятор отлавливает ее и выдает либо предупреждение, либо сообщение об ошибке в зависимости от конкретного типа компилятора. Замечание по технике программирования 5.3 При использовании вызова по значению в вызываемой функции можно изменять только одно значение. Это значение должно быть задано как возвращаемое в операторе return. Для модификации множества значений в вызываемой функции нужно использовать передачу параметров по ссылке. Хороший стиль программирования 5.4 Прежде, чем использовать функцию, проверьте прототип функции, чтобы определить, имеет ли она возможность модифицировать передаваемые ей значения. Существуют четыре способа передачи в функцию указателя: неконстантный указатель на неконстантные данные, неконстантный указатель на константные данные, константный указатель на неконстантные данные и константный указатель на константные данные. Каждая комбинация обеспечивает доступ с разным уровнем привилегий. Наивысший уровень доступа предоставляется неконстантным указателем на неконстантные данные - данные можно модифицировать посредством разыменования указателя, а сам указатель может быть модифицирован, чтобы он 5азывал на другие данные. Объявление неконстантного указателя на неконстантныу данные не содержит const. Такой указатель можно применить, чтобы передать строку в функцию, которая использует операции с указателем (и, возможно, модификацирует его) для обработки каждого символа в строке. Функция convertToUppercase на рис. 5.10 объявляет параметр sPtr(char *sPtr) как неконстантный указатель на неконстантные данные. Функция обрабатывает строку s символ за символом, используя арифметические операции с указателем. Символы в диапазоне от а до z преобразуются в соответствующие прописные буквы с помощью функции toupper;, а остальные символы остаются неизменными. Функция toupper получает в качестве аргумента символ. Если символ - строчная буква, возвращается соответствующая прописная буква; в противном случае возвращается исходная буква. Фзшкция toupper является частью библиотеки обработки символов ctype.h (смотри главу 16, Символы, строки, структуры и операции с битами ). (Замечание: функция toupper осуществляет преобразование только латинских букв, но не символов кириллицы.) Преобразование строчных букв в прописные с использованием неконстантного указателя на неконстантные данные Iinclude <iostream.h> ♦include <ctype.h> void convertToUppercase(char *); main() ( char string[] = characters and $32.98 ; cout << Строка перед преобразованием: << string << endl; convertToUppercase(string); cout Строка после преобразования: << string << endl; return 0; void convertToUppercase(char *sPtr) { while (*sPtr != \0) { *sPtr = toupper{*sPtr); преобразовать в прописные буквы ++sPtr; увеличить sPtr, чтобы указать на следующий символ Строка перед преобразованием: characters and $32.98 Строка после преобразования: CHARACTERS AND $32.98 Рис. 5.10. Преобразование строки в прописные буквы Неконстантный указатель на константные данные - это указатель, который можно модифицировать, чтобы указывать на любые элементы данных подходящего типа, но данные, на которые он ссылается, не могут быть модифицированы. Такой указатель можно было бы использовать, чтобы передать аргументы массивы функции, которая будет обрабатывать каждый элемент массива без модификации данных. Например, функция printCharacters на рис. 5.11 объявляет параметры sPtr типа const char *. Объявление читается как sPtr является указателем на константный символ . Тело функции использует структуру for для вывода каждого символа в строке до тех пор, пока не встретится нулевой символ. После того, как каждый символ будет напечатан, указатель sPtr увеличивается, чтобы указать на следующий символ в строке. Печать строки символ за символом с использованием неконстантного указателя на константные данные tinclude <iostream.h> void printCharacters(const char *); main() 1 char string[ ] = печать символов строки ; cout Строка: endl; printCharacters(string); cout << endl; return 0; В printCharacters sPtr - указатель на константный символ. Символы не могут модифицироваться посредством sPtr (т.е. sPtr - указатель только для чтения ) void printCharacters(const char *sPtr) { for (;*sPtr != \0; sPtr++) нет начального условия cout *sPtr; Строка: печать символов строки Рис. 5.11. Печать строки по символам с использованием непостоянного указателя на поаоянные данные Рисунок 5.12 демонстрирует сообщение об ошибке, вырабатываемое компилятором Borland С++ при попытке компилировать функцию, которая принимает неконстантный указатель на константные данные и затем пытается использовать этот указатель для модификации данных. Как мы знаем, массивы - это агрегаты типов данных, которые хранят связанные элементы данных одинакового типа с одинаковым именем. В главе 6 мы обсудим другую форму агрегирования типов данных, называемую структурой (иногда называемую в других языках записью). Структуры способны хранить связанные элементы данных разных типов под одним именем (например, хранить информацию о каждом служащем компании). При вызове
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |