Лекция 4 по си++ фкн вгу

Лекция 4 по си++

Примеры структур:
struct String {
const char* p;
size_t len;
};
1) String s;
2) String s = {“Str”, 3}; // инициализация структуры.

Все члены структур – публичные - и наследуются как публичные.
Алгоритмы же обычно выносят в классы.
struct { // описание структуры без описания типа
const char* p;
size_t len;
} s; // имя переменной структуры
struct {
const char* p;
size_t len;
} s = {“Str”, 3};

Отличия С структур от С++ структур.

Имеются два существенных различия:
1) Во-первых структуры в си++ имеют уникальные идентификаторы (например public)
2) Не обязательно после объявления нового типы структуры использовать слово struct для объявления новой переменной. – хотя этот пункт сомнителен , ибо ,компилируется в си ()

Препроцессор:

#include
#include “resource.h” // пользовательский
#define INT_VALUE 1 // препроцессор заменит константу на значение.
#undef INT_OLD_VALUE //
int main()
{
int i = INT_VALUE;
return i; // вернёт единицу
}

#include // в системных каталогах
#include “имя_файла” // в текущем каталоге

// Примеры:
#include
#include
#include “string”
#include “test.cpp”
#include “func.def”
// main.cpp
#include
#include “test.inc”
int main()
{
func();
return 1;
}

// main.cpp
#include
int max(int a, int b)
{
#include “func.inc”
}
int main() { …}

------------------------------
Директива define

#define ИМЯ текст_подстановки
#define ИМЯ(параметры) текст_подстановки
#define ИМЯ
#undef ИМЯ
// Примеры:
#define VERSION 1
#define LOG_PATH “/var/logs/syslog.log”
#define MAX(x, y) ((x)>(y)?(x):(y))
#define __GCC__

Условная компиляция (с помощью предварительного использования define - в случае пользовательских констант - или же проверки системных переменных
)
// Синтаксис:
#if выражение

[ #elif выражение
… ]
[ #elif выражение
… ]
[ #else
… ]
#endif

Ещё пример :

// Пример:
#if VERSION == 1 // если одна версия
#define INCFILE “version1.h” // то вот это файл подключаем
#elif VERSION == 2
#define INCFILE “version2.h”
#else
#error What version? // если версия не указана – сообщаем об ошибке.
#endif
#include INCFILE

Различные варианты:
) #if выражение
2) #ifdef ИМЯ
3) #ifndef ИМЯ
4) #if defined(ИМЯ) …
5) #if !defined(ИМЯ) …
6) #elif defined(ИМЯ) …
7) #elif !defined(ИМЯ) …

// Примеры:
#if (defined(_WIN32) || defined(WIN32))
// заголовочные файлы windows
#elif (defined(__linux__) || defined(__linux))
// заголовочные файлы linux
#elif (defined(__MACOSX__))
// заголовочные файлы macos
#else
#error ERROR: Unsupported platform
#endif

Ещё примеры для препроцессора в си:

#if !defined(__cplusplus)
#error Need C++ compiler
#endif
#define TEST(e) if(!(e)) \
printf("Error in %s:%i - %s", __FILE__, __LINE__, #e)
// __FILE__, __LINE__ -компилятор тот файл и ту строчку, которую проходит.
int Test() {
return 0;
}
TEST(Test());
// Результат:
// Error in c:\dev\test\test\test.cpp:21 - Test()

Предопределённые макросы

// С++
1) __DATE__
2) __FILE__
3) __LINE__
4) __TIME__
5) __FUNC__
6) __cplusplus
// MSVC – МелкоСофт виЖуал (от слова «вижу») студио
• _DEBUG
• WIN32
• WIN64
• _UNICODE
• _CONSOLE
• _MSC_VER

Типы памяти в си++

В си++ есть четыре типа памяти:
• константная память; // для хранения констант
• стек;
• динамическая память;
• глобальная / статическая.

Константная память
Используется для констант - при попытке изменить полезет ошибка . пример:
const int i = 5; // константа
сhar* p1 = “Строка”;
Указатель на константу:
const char* p2 = “Строка”;
int b = 10;
p2 = &b;
*p2 = 20;

Константный указатель:
int a = 10;
int b = 20;
int* const p;
int* const p1 = &a;
*p1 = 30;
p1 = &b;

Константный указатель на константу:
int a = 10;
int b = 20;
const int* const p;
const int* const p1 = &a;
*p1 = 30;
p2 = &b;

• Константная память пример 2
Константный указатель:
int a = 10;
int b = 20;
int* const p; // не скомпилируется – при описании константы надо указывать его значение.
int* const p1 = &a;
*p1 = 30;
p1 = &b; // так делать нельзя - ошибка
• Константная память пример 3
Константный указатель на константу:
int a = 10;
int b = 20;
const int* const p; // ошибка
const int* const p1 = &a;
*p1 = 30; // ошибка
p2 = &b; //ошибка

Стековая память

• Стековая память
void func()
{
char b[256]; string s; string s(“Строка”);
}
int b = 20; // не стековая
int main()
{
int b = 20;
return 1;
}

Динамическое выделение – динамическая память.
void* malloc(size_t n);
void* realloc(void* p, size_t n);
void free(void* p);
void* operator new(size_t n);
void* operator new[](size_t n);
void operator delete(void* p);
void operator delete[](void* p);
• Динамическая память пример 1
сhar* p = new char; // delete
char* p1 = new char(10); // delete
сhar* p2 = new char[10]; // delete []
string* s = new string(“Строка”); // delete
int* q = (int*)malloc(10*sizeof(int)); // free

• Динамическая память пример 2
void* __cdecl operator new(size_t n)
{
return malloc(n);
}
void __cdecl operator delete(void* p)
{
free(p);
}
void* __cdecl operator new[](size_t n)
{
return malloc(n);
}
void* __cdecl operator delete[](void* p)
{
free(p);
}
• Динамическая память пример 3
// placement new
void* operator new(size_t n, void* p) // delete ?
{
return p;
}
char* p = new char;
new(p) char(10);
char* p1 = new(10) char; // ошибка - бессмыслица (по словам преп.)

для всех объектов следует писать корректные конструкторы и конкретные деструкторы.

• Динамическая память пример 4 ?
class A {
public:
A(int a, int b){ _a = a; _b = b; }
private:
int _a; int _b;
};
int q[2];
A* p = (A*)q;
new(p) A(10, 10);

Глобальная память
int i = 10;
string s; string s(“Строка”);
int main()
{
return 1;
}

• Статическая память
void func()
{
static int i = 10;
i++;
}
func(); // i = 11;
func(); // i = 12;
• Области действия(видимости)
• класс;
• структура;
• объединение;
• блок;
• пространства имён.
• Блоки
void func()
{
int i = 10;
{
int i = 20;
i++;
}
i++;
}
• Пространства имён 1
int i = 0;
int main()
{
int i = 1;
i++;
::i++;
return 0;
}
• Пространства имён 2
namespace имя
{
int b = 5;
typedef int bool_t;
void func();
class string;
}
using namespace имя;
• Пространства имён 3
int i = 20;
namespace x {
int i = 10;
}
void func()
{
::i++; // 21
x::i++; // 11
::x::i++; // 12
}
• Пространства имён 4
namespace x {
int a = 20;
namespace y {
int b = 10;
}}
x::a++; x::y::b++;
using namespace x::y;
b++;
a++;
• Пространства имён 5
int i = 10;
namespace x
{
int i = ::i;
}
using namespace ::x;
i++;
• Простанства имён 6
namespace x{
namespace y{
int b = 10;
}
using namespace y;
int c = b;
}
using namespace x;
c++;
b++;
• Пространства имён 6
#include
string s;
using namespace std;
string s1;
int main()
{
std::string s;
return 1;
}
• Выделение памяти
На стеку:
String o;
int i;
char b[256];
void func()
{
char p[100];
}
Динамическое:
String* o = new String();
delete o;
void func()
{
int* p = new int[100];
}
• Классы
class имя {
операции;
public:
описание элементов/операции;
protected:
описание элементов/операции;
private:
описание элементов/операции;
};
• Пример объявления класса
class String
{
public:
String();
~String();
public:
void Test();
};
class Text
{
public:
Text();
public:
void SetText(char* p);
char* GetText();
};
• Конструктор
class String
{
public:
String(){}
};
class String
{
public:
String();
};
inline String::String()
{
}
• Деструктор
class String
{
public:
~String(){}
};
class String
{
public:
~String();
};
inline String::~String()
{
}
• Объявление и реализация
String.h
class String
{
public:
String();
~String();
};
String.cpp
#include “String.h”
String::String()
{
}
String::~String()
{
}
• Создание объекта класса
class String {
public:
String() {
printf(“String\n”);
}
~String() {
printf(“~String\n”);
}
};
#include
int main()
{
String* s = new String();
delete s;
String b;
return 1;
}