КОМПЬЮТЕРНАЯ ЛИТЕРАТУРА - Турбо С: руководство пользователя. Часть 2 - Стр. 35

Индекс материала
Турбо С: руководство пользователя. Часть 2
Стр. 2
Стр. 3
Стр. 4
Стр. 5
Стр. 6
Стр. 7
Стр. 8
Стр. 9
Стр. 10
Стр. 11
Стр. 12
Стр. 13
Стр. 14
Стр. 15
Стр. 16
Стр. 17
Стр. 18
Стр. 19
Стр. 20
Стр. 21
Стр. 22
Стр. 23
Стр. 24
Стр. 25
Стр. 26
Стр. 27
Стр. 28
Стр. 29
Стр. 30
Стр. 31
Стр. 32
Стр. 33
Стр. 34
Стр. 35
Стр. 36
Стр. 37
Стр. 38
Стр. 39
Стр. 40
Стр. 41
Стр. 42
Стр. 43
Стр. 44
Стр. 45
Стр. 46
Стр. 47
Стр. 48
Стр. 49
Стр. 50
Стр. 51
Стр. 52
Стр. 53
Стр. 54
Стр. 55
Стр. 56
Все страницы
          int pascal q(void); /* Функция типа pascal, возвращающая */           
                                 /* целое; параметры не передаются */           
                                                                                
          char far * s(char *source, int kind); /* Функция возвра- */           
                              /* щает указатель типа far на строку,*/           
                 /*а получает два параметра: типа char* и типа int */           
                                                                                
          int printf(char *format,...);      /* Функция возвращает */           
                           /* значение типа int, получая указатель */           
                            /* на фиксированный параметр типа char */           
                   /* и любое количество дополнительных параметров */           
                                              /* неизвестного типа */           
                                                                                

                         - 285,286 -
                                                                                
          int (*fp)(int);    /* Указатель на функцию, возвращающую */           
                                /* целое и получающую единственный */           
                                                 /* целый параметр */           
                                                                                
          Ниже приводятся правила, регламентирующие работу с модифика-          
     торами языка и формальными параметрами в  вызовах  функций  Турбо          
     Си, как использующих прототипы, так и не использующих их:                  
                                                                                
     Правило #1. Модификаторы языка для описания функций должны совпа-          
                 дать с   модификаторами,  используемыми в объявлении           
                 функции, для всех обращений к функции.                         
                                                                                
     Правило #2. Функция  может изменять значения формальных  парамет-          
                 ров, но   это не оказывает какого-либо воздействия на          
                 значения действительных аргументов в вызывающей прог-          
                 рамме, за исключением функций прерывания. Для большей          
                 информации смотрите "Функции прерывания" в главе 12.           
                                                                                
          Если прототип функции не объявлен предварительно,  то  Турбо          
     Си преобразует   целочисленные  аргументы при обращении к функции          
     согласно правилам, приведенным в разделе "Арифметические преобра-          
     зования". Если прототип объявлен,  то Турбо Си преобразует задан-          
                                                                                
     ные аргуметы к типу, назначенному для параметров.                          
                                                                                
          Если прототип функции включает элипсис (...),  то  Турбо  Си          
     преобразует все   заданные  аргументы  функции как в любом другом          
     прототипе (до элипсиса).  Компилятор будет расширять любые  аргу-          
     менты, заданные после фиксированного числа параметров по нормаль-          
     ным правилам для аргументов функций без прототипов.                        
                                                                                
          Если есть прототип, то число аргументов должно быть соответ-          
     ственным (за исключением случая,  когда  в  прототипе использован          
     элипсис).  Типы должны  быть  совместимы  только  по размеру, для          
     того  чтобы  корректно  производились  преобразования  типов.  Вы          
     всегда  должны  использовать  явные  преобразования  аргументов к          
     типу, допустимому для прототипа функции.                                   
                                                                                
          Следующий пример прояснит данные замечания:                           
                                                                                
        int strcmp(char *s1, char *s2);       /* Полный прототип */             
        int *strcpy();                          /* Нет прототипа */             
        int samp1(float, int, ...);            /* Полный прототип */            
                                                                                
        samp2()                                                                 

                         - 287,288 -
                                                                                
        {                                                                       
        char *sx, *cp;                                                          
        double z;                                                               
        long a;                                                                 
        float q;                                                                
                                                                                
        if (strcmp(sx, cp))      /* 1. Верно */                                 
            strcpy(sx,  cp,  44);/* 2. Верно, но не переносимо из               
                                                          Турбо Си */           
                                                                                
        samp1(3, a, q);          /* 3. Корректно */                             
        strcpy(cp);              /* 4. Ошибка при выполнении */                 
        samp1(2);                /* 5. Ошибка при компиляции */                 
                                                                                
        }                                                                       
                                                                                
          Пять вызовов (каждый с комментарием)  примера  демонстрируют          
     различные варианты вызовов функций и прототипов.                           
                                                                                
          В вызове No 1 использование функции strcmp явно соответству-          
     ет прототипу, что справедливо для всех случаев.                            
                                                                                
                                                                                
          В вызове No 2  обращение  к  strcpy  имеет  лишний  аргумент          
     (strcpy определена  для двух аргументов,  а не для трех).  В этом          
     случае Турбо Си теряет небольшое количество времени и создает код          
     для помещения лишнего аргумента в стек.  Это, однако, не является          
     синтаксической ошибкой, поскольку компилятор не знает о числе ар-          
     гументов strcpy. Такой вызов не допустим для других компиляторов.          
                                                                                
          В вызове  No 3  прототип требует,  чтобы первый аргумент для          
     samp1 был преобразован к float,  а второй - к int. Компилятор вы-          
     даст предупреждение   о  возможной потере значащих цифр поскольку          

     при преобразовании типа long к типу int отбрасываются старшие би-          
     ты. (Вы можете избавиться от такого предупреждения, если зададите          
     явное преобразование к целому.) Третий аргумент, q, соответствует          
     элипсису в   прототипе.   Он преобразуется к типу double согласно          
     обычному арифметическому преобразованию.  Вызов полностью коррек-          
     тен.                                                                       
                                                                                
          В вызове  No 4 снова вызывается strcpy,  но число аргументов          
     слишком мало. Это вызовет ошибку при выполнении программы. Компи-          
     лятор будет   молчать  (если  даже число параметров отличается от          
     числа параметров в предыдущем вызове той же функции),  т.к.   для          
     strcpy не определен прототип функции.                                      

                         - 289,290 -
                                                                                
                                                                                
                                                                                
          В вызове  No 5 функции samp1 задано слишком мало аргументов.          
     Т.к. samp1  требует минимум два аргумента, этот оператор является          
     ошибочным. Компилятор    выдаст сообщение о том,  что в вызове не          
     хватает аргументов.                                                        
                                                                                
          Важное замечание: если ваш прототип функции не соответствует          
     действительному определению функции,  то Турбо Си обнаружит это в          
     том и только в том случае,  если это определение находится в  том          
     же файле,  что и прототип. Если вы создаете библиотеку программ с          
     передаваемым набором прототипов (файлом include),  то  вы  должны          
     учитывать включение  файла с прототипами во время компиляции биб-          
     лиотеки, с  целью выявления любого противоречия между прототипами          
     и действительными определениями функций.                                   
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
               Правила видимости (K&R 11)                                       
     -----------------------------------------------------------------          
                                                                                
          Турбо Си разрешает более свободное обращение с неуникальными          
     идентификаторами, чем того требует K&R.  В Турбо Си различают че-          
     тыре класса идентификаторов:                                               
                                                                                
          Переменные, имена   новых   типов,   описываемых  с  помощью          
     typedef, и  перечисленные члены должны  быть  уникальными  внутри          
     блока, в котором они описаны. Идентификаторы, объявленные внешни-          
     ми, должны быть уникальными среди переменных, описанных как внеш-          
     ние.                                                                       
                                                                                
          Имена структур,  объединений и перечислений должны быть уни-          
     кальными внутри блока,  в котором они описаны. Эти имена, описан-          
     ные вне пределов какой-либо функции,  должны быть уникальны среди          
     всех соответствующих имен, описанных как внешние.                          
                                                                                
          Имена членов структуры и  объединения должны быть  уникальны          
     в структуре или объединении, в которых они описаны. Не существует          
     никаких ограничений на тип или смещение для  членов с одинаковыми          
     именами в различных структурах.                                            

                         - 291,292 -
                                                                                
                                                                                
                                                                                
          Метки  на  которые  ссылаются   операторы  goto  должны быть          
     уникальными внутри функции, в которой они определены.                      
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
               Команды управления трансляцией (K&R 12)                          
     -----------------------------------------------------------------          
                                                                                
          Турбо Си поддерживает все управляющие команды, описанные в K          
     &R. Этими командами являются директивы препроцессора - строки ис-          
     ходной программы,  начинающиеся со знака #,  за которым или перед          
     которым может следовать символ пробела или табуляции.                      
                                                                                
                                                                                
                                                                                
               Замена лексем (K&R 12.1)                                         
     -----------------------------------------------------------------          
                                                                                
          Турбо Си поддерживает определения K&R для  #define и  #undef          
     со следующими дополнениями:                                                
                                                                                
          1. Ниже приведенные идентификаторы не должны  встречаться  в