|
Программирование >> Процедурные приложения
\nфайл недоступен.\n , \nВведенный символ не является алфавитно-цифровIм.\n , \пЧисло не попадает в диапазон от 1 до 10.\n FILE *fopen a file (char *psz) char cget a char (void) ; int ,iget an integer (void) ; FILE *pfa file; void main () { char cvalue; int ivalue; fopen a file( input.dat ); cvalue = cget a char() ; ivalue = iget an ihteger() , FILE *fopen a file(char *psz) const ifopen a file error = 0; pfa file = fopen(psz, r ); if (!pfa file) printf( %s ,pszarray [ifopen a file error] ); return (pfa f ile ); char cget a char(void) { char cvalue; const .icget a char error = 1; printf( \nВведитебукву: ); scanf( %c ,&cvalue); if(!isalpha (cvalue)) printf( %s ,pszarray[icget a char error]); return(cvalue); } int iget an integer (void) { int ivalue; const iiget an integer =2; printf( \nВведите целое число в диапазоне от 1 до 10: ); scanf( %d , sivalue) ; if ((ivalue< 1) I (ivalue > 10) ) printf( %s , pszarray [iiget an integer] ); return (ivalue) ; } Массив pszarray объявлен вне функций, поэтому является глобальным. Обратите внимание, что в каждой из трех функций - fopen a file() , cget a char () и iget an integer() - используется свой индекс для обращения к массиву. Подобный подход позволяет организовать весьма гибкую и надежную систему сообщений об ошибках, так как все такие сообщения локализованы в одном месте и ими легче управлять. Ссылки в языке C++ Язык C++ предоставляет возможность прямого обращения к переменным по адресам, что даже проще, чем использовать указатели. Аналогично языку С, в C++ допускается создание как обычных переменных, так и указателей. В первом случае резервируется область памяти для непосредственного сохранения данных, тогда как во втором случае в памяти компьютера выделяется место для хранения адреса некоторого объекта, который может быть создан в любое время. В дополнение к этому язык C++ предлагает третий вид объявления переменных - ссылки. Как и указатели, ссылки содержат данные о размещении других переменных, но для получения этих данных не нужно использовать специальный оператор косвенного обращения. Синтаксис использования ссылок в программе довольно прост: int iresult a = 5; int& riresult a = iresult a; допустимое создание сс1лки int$ riresult b; недопустимо, поскольку нет инициализации В данном примере создается ссылка (на это указывает символ & после имени типа данных) riresult a, которой присваивается адрес существующей переменной iresult a. С этого момента на одну и ту же ячейку памяти ссылаются две переменные: iresult aи riresult a. По сути, это два имени одной и той же переменной. Любое присвоение значения переменной riresult a немедленно отразится на содержимом переменной iresult a. Справедливо и обратное утверждение: любое изменение переменной iresult a вызовет изменение значения переменной riresult a. Таким образом, можно сказать, что использование ссылок в языке C++ позволяет реализовать систему псевдонимов переменных. В отличие от указателей, на ссылки накладывается следующее ограничение: их инициализация должна производиться непосредственно в момент объявления, и однажды присвоенное значение не может быть изменено в ходе выполнения программы. То есть если при объявлении ссылки вы присвоили ей адрес какой-либо переменной, то эта ссылка на протяжении всего времени работы программы будет связана только с этой ячейкой памяти. Вы можете свободно изменять значение переменной, но адрес ячейки, указанный в ссылке, изменить невозможно. Таким образом, ссылку можно представить как указатель с константным значением адреса. Рассмотрим некоторые примеры. В следующей строке значение, присвоенное выше переменной iresult a(в нашем примере - 5), будет удвоено: riresult a *= 2; Теперь присвоим новой переменной icopy value(предположим, что она имеет тип int) значение переменной iresult a, используя для этого ссылку: icopy value = riresult a; Следующее выражение также является допустимым: int *piresult a = &riresult a; Здесь адрес ссылки riresult a (т.е., посути, адрес переменной iresult a) присваивается указателю piresult a типа int. Функции, возвращающие адреса Когда функция возвращает указатель или ссылку, результатом выполнения функции становится адрес в памяти компьютера. Пользователь может прочитать значение, сохраненное по этому адресу, и даже, если указатель не был объявлен со спецификатором const, записать туда свои данные. Это может привести к возникновению трудно обнаруживаемых ошибок в программах. Посмотрим, сможете ли вы разобраться в том, что происходит в следующей программе. refvar.cpp Эта программа на языке C++ демонстрирует, чего НЕ нужно делать с адресами переменных. #include <iostream.h> int *ifirst function(void) ; int *isecond function(void); void main(){ int *pi = ifirst function (); isecond function(); cout<< Это значение правильное? << *pi; } int *ifirst function(void){ int ilocal to first = 11; return &ilocal to first; int *isecond function(void){ int ilocal to second = 44; return &ilocal to second;} Запустив программу, вы убедитесь, что она выводит значение 44, а не 11. Как такое может быть? При вызове функции ifirst function() в программном стеке резервируется место для локальной переменной ilocal to first и по соответствующему адресу записывается значение 11. После этого функция ifirst function() возвращает адрес этой локальной переменной в основную программу (сам по себе малоприятный факт - компилятор выдает по этому поводу лишь предупреждение, но, увы, не ошибку). В следующей строке программы вызывается функция isecpnd function(), которая, в свою очередь, резервирует место для переменной ilocal to second и присваивает ей значение 44. Почему же оператор cout выводит на экран значение 44, если ему был передан адрес переменной ilocal to first? А произошло вот что. Указатель pi получил адрес ячейки, в которой хранилось значение локальной переменной ilocal to first, присвоенное ей во время выполнения функции ifirst function (). Указатель pi сохранил этот адрес даже после того, как переменная ilocal to first вышла за пределы своей области видимости по завершении функции. При этом ячейка памяти, которую занимала переменная ilocal to firstи адрес которой записан в указателе pi, оказалась свободной, и ее тут же использовала функция isecond function () для сохранения своей локальной переменной ilocal to second. Но поскольку адрес ячейки в указателе piне изменился, то на экран будет выведено значение переменной ilocal to second, а не ilocal to first. Мораль такова: нельзя допускать, чтобы функции возвращали адреса локальных переменных.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |