Информатика (2 семестр)

advertisement
С++

Язык программирования С++ был разработан на основе языка С
Бьярном Страуструпом (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);
}
// перекрыть глобальную операцию
Download