С++ Язык программирования С++ был разработан на основе языка С Бьярном Страуструпом (Bjarne Stroustrup). С++ На первых порах (1980 год) язык носил условное название «С с классами», а в 1983 году Рик Массити придумал название «С++» Предшественники С++: C – BCPL – SIMULA 67 – Алгол 68 С++ является надмножеством С, поэтому программы написанные на Си, могут обрабатываться компилятором языка С++ На сегодняшний день язык Си++ является одним из наиболее универсальных языков программирования. Его использование лежит, в основном, в области создания высокоэффективных приложений пользовательского уровня, работающих со сложными динамическими структурами данных. Многие из таких приложений могут быть созданы средствами других языков, таких как Java, Perl или Phyton. Но быстродействие результирующего кода, созданного компиляторами с языка Си++, находится вне конкуренции с кодом вышеперечисленных языков. C++ как улучшенный С Лучший метод перевести программу с С на С++ просто перекомпилировать ее и проследить все появляющиеся ошибки Отличие C++ от С 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. аргументы, используемые по умолчанию ссылки параметры-ссылки функция, возвращающая значение типа ссылки встроенные функции операция :: перегруженные функции определение переменных константные значения имена-этикетки в enum, struct и union анонимные объединения гибкие операторы распределения памяти 1. Аргументы, используемые по умолчанию void ShowMessage(char *msg, int x=0, int y=0); void ShowMsg( int x, int y=0, char *msg); ShowMessage(” Error: Out of Memory ”, ,10); ShowMessage(” Error: Out of Memory ”); ShowMessage(” Error: Out of Memory ”,10); //неверно //неверно 2. Ссылки #include <stdio.h> int value=10; int &refval=value; int main(void) { printf(” value = %d \n ”, value); refval +=5; // Модификация через ссылку printf(” value = %d \n ”,value); // 15 printf(” Адрес value равен %p \n ”, &value ); printf(” Адрес refval равен %p \n ”, &refval ); // Одинаково return(0); } 3. Параметры-ссылки #include <stdio.h> void Inc_val(int i) { i++; } // Получает параметр значением. Модификация не // влияет на оригинал void Inc_ptrl(int *i) { (*i)++; } // Получает адрес оригинала. Модифицирует // оригинал путем косвенной адресации void Inc_ref(int &i) { i++; } // Получает параметр ссылку. Модифицирует // оригинал !!!!! int main(void) { int j=10; printf(” J равняется %d\n”,j); Inc_val(j); printf(” j=%d\n ”),j); Inc_ptr(&j); printf(” j=%d\n ”),j); Inc_ref(j); printf(” j=%d\n ”),j); return(0); } 4. Функция, возвращающая значение типа ссылки #include <stdio.h> const int arraySize=0xF; static int valArray[arraySize]; int& valueAt(int indx) { return valArray[indx]; } #include <assert.h> int main(void) { for (int i=0; i<arraySize; i++) valueAt(i) = 1; int& valueAt(int indx) for (int i=0; i<arraySize; i++) { printf(” Значение[%d]=%d\n ”, i , valueAt(i); assert(indx >= 0); assert(indx < arraySize); return(0); return valArray[indx]; } } 5. Встроенные (inline) функции #include <stdio.h> inline void swap(int &i, int &j) { i ^= j ^= i ^= j; } // ^= присвоение исключающего ”или” (выполняется справа налево) int main(void) { int a=10, b=20; printf(” a=%d, b=%d \n ”,a,b); swap(a,b); printf(” a=%d, b=%d \n ”,a,b); return 0; } Борланд С++ не допускает inline-расширений для функций: применяющих операторы while, do/while, switch/case, for, goto; имеющих тип void и не содержащих оператора return; применяющих встроенный код ассемблера. Компилятор выдаст сообщение об ошибке int i , j; int min(int i1, int i2); // прототип int main(void) { return min(i , j); } // Вызов inline int min(int i1, i2) { return i1 > i2 ? i2 : i1; } // Определение Компилятор не выдаст сообщение об ошибке int i , j, k , l; inline int max(int i1, int i2); // прототип int func1(void){return max(i , j);} // не расширяется как inline inline int max(int i1, i2) { return i1 > i2 ? i1 : i2; } int func2(void) {return max(i , j);} // расширяется как inline !!! 6. Операция :: #include <stdio.h> int total=10; // Глобальная переменная int main(void) { int total=100; // Локальная переменная во внешней области действия if (total > 0) { int total = 1000; // Локальная переменная во внутренней области printf(” Локальная total %d\n ”,total); printf(” Глобальная total %d\n ”,::total); } return 0; } } 7. Перегруженные функции #include <stdlib.h> #include <stdio.h> void ShowMessage(int); void ShowMessage( char *msg); void ShowMessage(int errCode) { printf(«MSG: %s\n, sys_errlist[errCode]);} void ShowMessage(char *msg) { printf(«MSG: %s\n»,msg); } int main(void) { ShowMessage(1); // 1: Недействительный номер функции ShowMessage (” Ошибка исправлена ”); return 0; } Функции, отличающиеся только типом возвращаемого значения, не могут быть перегружены. Следующий код вызовет ошибку: int getCustInfo(char *name); char *getCustInfo(char *name); Функции не могут быть перегружены, если их параметры различаются только применением модификаторов const или volatile , или использованием ссылки. void DelRec(int indx); void DelRec(int &indx); void DelRec(const int indx); void DelRec(volatile int indx); Ниже показаны некоторые внутренние имена перегруженных функций: void func(int i); @func$qi int func(int i); @func$qi void func(char i); @func$qc void func(char *p); @func$qp. 8. Определения переменных #include <stdio.h> int main(void) { printf(” Привет!\n ”); int i; printf(” Значение i= %d \n ”, i); for ( int j=0; j<10; j++) // переменные определяются там, где в них появляется необходимость { printf(” j=%d\n ”,j); printf(” Текущее значение j=%d\n ”,j); } } 9. Константные значения const double pi = 3.1415926535897932385; const char plus = '+'; Описание const гарантирует, что его значение не изменится в области видимости: const int model = 100; model = 145; model++; // ошибка // ошибка 10. Имена-этикетки в enum, struct и union enum Account {edu, corp, persnl }; enum { ASM, AUTO, BREAK }; struct custInfo { char name[80]; long accntNum; Account AccType; }; // вместо enum Account AccType custInfo c={” FD, Ltd.”,100,corp}; // без ключа struct 11. Анонимные объединения #include <string.h> static union { char custName[80]; long custId; }; // Глобальное объединение int main(void) { union { int newId; // Локальное объединение int counter; }; for (counter=0; counter<10; counter++) custId=counter; strcpy(custName, ” New ”); newId=0x100; return 0; } 12. Гибкие операторы распределения памяти #include <stdlib.h> #include <stdio.h> long *lptr; void f1(void) { lptr=(long* )malloc(sizeof(long)); *lptr=0x1000; printf(” Значение равно %d\n ”, *lptr); free(lptr); } void f2(void) { lptr=new long; *lptr=0x1000; printf(” Значение равно %d\n ”, *lptr); delete lptr; } set_new_handler – определяемая пользователем процедура обработки ошибок #include <stdio.h> #include <stdlib.h> #include <new.h> void MyNewHandler( ) { printf(” Нет памяти!\n ”); } int main(void) { set_new_handler(MyNewHandler); return 0; } // Установит новый обработчик.. Переопределение new[ ] и delete[ ] void* operator new(size_t); void* operator new[ ](size_t); void operator delete(void*); void operator delete[ ](void*); #include <stdio.h> #include <stdlib.h> void* operator new(size_t size) // перекрыть глобальную операцию { printf(” new( ) запрашивает %d байт \n ”,size); return malloc(size); } void operator delete(void *p) { printf(” delete() \n ”); free(p); } // перекрыть глобальную операцию