Научно-образовательный IT-форум при КНИТУ-КАИ

Объявление

Семинар на тему «Восстановление кривых изменений вегетационных индексов по данным космической съемки (на примере индекса NDVI)» Д.А. Колесов (NextGIS). Дата и время: 24.11.2017 в 15.00; адрес: г.Казань, ул. Б.Красная, д.55, ауд. 428.

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.



Основы С++ (Е.М. Линский, 2011 г.)

Сообщений 1 страница 4 из 4

1

Особое внимание в курсе уделено следующим темам:
- Эффективная работа с памятью
- Объектно-ориентированное программирование на примере языка C++
- Обобщенное программирование на примере языка C++
- STL

Видеолекции

http://forumfiles.ru/files/000c/4b/84/94641.png

Материалы

http://forumfiles.ru/files/000c/4b/84/76762.gif

2

Вопрос: Почему не работает указанный код?

Код:
#include <string>
#include <iostream>
using namespace std;

struct a {
	string str;
	int b;
};

void main() {
	a c[3];
	for(int i=0; i<3; i++)	{
    getline(cin,c[i].str);
    cin >> c[i].b;
	}
}

Ответ:
Правильный код:

Код:
#include <string>
#include <iostream>
using namespace std;

struct a {
	string str;
	int b;
};

void main() {
	a c[3];
	for(int i=0; i<3; i++)	{
    getline(cin,c[i].str);
    cin >> c[i].b;
    cin.ignore();
	}
}

Справка:
Функция ignore() используется с потоками ввода. Она считывает и выбрасывает символы, пока не считает num символов (по умолчанию num равен 1) или пока не считает символ-ограничитель delim (по умолчанию delim равен EOF). Функция ignore() иногда полезна при использовании вместе с функцией getline() и оператором >>. Например, если вы считываете некоторые данные, которые следуют за символом новой строки, с помощью оператора >>, символ новой строки останется не считанным и будет прочитан следующим. Так как getline() по умолчанию останавливает считывание по достижению символа новой строки, последующий вызов функции getline() возвратит пустую строку. По этой причине следует вызывать ignore() до getline(), чтобы выбросить символ новой строки.

3

Вопрос: Какой размер объекта типа string?

Ответ:
Тип данных String представляет текст как последовательность знаков Юникод. Каждая строка представляет собой упорядоченный массив из нуля или более символов Юникод (т.е. 2-байтовых целых чисел без знака), называемых элементами строки. Элементы строки нумеруются, начиная с нуля. Длина строки - это количество элементов в ней; пустая строка состоит из нуля элементов.
Строка может содержать до 2 Гб данных.

Справка:
2 Гб - это максимальный, теоретически возможный размер, который могут хранить в себе строковые переменные. Данный размер обусловлен максимальным размером длины строки, установленным для типа String - 4 байта. На практике максимальный размер значения, которое может храниться в строковой переменной, зависит от множества факторов.
В архитектуру операционных систем заложено резервирование части оперативной памяти на нужды самой операционной системы и части для нужд пользовательских приложений. 32-битные процессы используют 32-битные указатели на адреса в виртуальной памяти, которые создают абсолютный верхний предел в 4 Гб (2 ^ 32-ой степени). По умолчанию 32-битная версия Windows разделяет адресное пространство поровну между системой и приложениями, создавая границу в 2 Гб для каждого. (При определенных настройках можно достичь соотношения 1/4 на нужды ОС и 3/4 на нужны приложений). 64-битные процессы используют 64-битные указатели, так что их теоретическое максимальное адресное пространство равно 16 экзабайтам (2 ^ 64-ой степени). Однако, Windows не делит адресное пространство равномерно между активными процессами и системой, а вместо этого определяет область в адресном пространстве для процессов и других системных ресурсов памяти. В 64-битной версии Windows для пользовательских приложений доступно использование адресного пространства в 8192 Гб (8 Тб).
Для каждого приложения операционная система выделяет непрерывный блок памяти, требуемый для работы. При каких-либо операциях с данными также резервируются непрерывные блоки памяти для временных переменных, используемых при вычислениях.
В реальных условиях работа запущенных приложений, служб приводит к фрагментации памяти. Это в свою очередь проводит к ограниченному количеству и объему доступных свободных непрерывных блоков памяти. В ситуациях, когда приложение достигает предела доступного адресного пространства памяти, либо когда ОС по каким-либо причинам не может выделить приложению необходимый объем памяти, генерируется исключительная ситуация «Недостаточно памяти».
Все эти ограничения приводят к тому, что на разных ПК с различными ОС всегда будет различным доступный объем памяти, который сможет использовать Prognoz Platform 8. Это в свою очередь накладывает ограничение на максимально доступный размер данных, который можно хранить в переменных. Необходимо избегать операций с большими объемами данных, оптимизируя алгоритмы для работы с отдельными частями данных.

4

Вопросы по лекции №5:

1. объясните почему первый параметр у функции strtok  иногда является NULL?
2. также не до конца понял смысл работы функций atoi & atof . Написано, что они преобразуют строки в числа) но по какому принципу?

Ответы:

1. Если коротко отвечать, то в этом случае функция продолжает сканирование с того места, где был остановлен предыдущий успешный вызов функции. :) Подробнее см. ниже.

Функция strtok выделяет очередную часть строки, на которую указывает аргумент str, отделенную одним из символов разделителей указанных в строке, на которую указывает аргумент sep. Последовательный вызов функции strtok приводит к разбиению строки str на части (лексемы).

При первом вызове функции strtok указывается начало разделяемой строки (str) и начало строки, содержащей разделители (sep). Функция strtok поочередно просматривает символы строки str и ищет первое вхождение символа, не содержащегося в строке разделителей sep. Если символ конца строки встречен раньше чем был найден символ не входящий в строку sep, то разделить строку str на части нельзя и возвращается нулевой указатель (NULL). Если такой символ найден, он считается началом первой части строки str.

Далее функция strtok ищет разделитель, то есть символ, входящий в строку sep. Если такой символ не найден, то считается, что строка str состоит из одной части и последующее разделения строки str будут возвращать нулевой указатель. Если такой символ найден. то он заменяется нулевым символом (символом конца строки). Далее функция strtok запоминает текущую позицию (указатель на символ, с которого будет начинаться поиск следующей части строки) и возвращает указатель на начало первой выделенной части строки.

Если функция strtok вернула не нулевой указатель, можно продолжить разбиение строки str на части. Для продолжения разбиения строки, повторно вызывается функция strtok, но вместо указателя на разбиваемую строку в качестве первого аргумента указывается NULL. В этом случае функция strtok продолжит разбиение с запомненного адреса. Алгоритм разбиения при этом останется тот же.

2. Эти функции превращают массив символов (строку), которая хранит число в один из числовых типов (первая функция в double, вторая в int). Например:

Код:
#include <iostream>
#include <cstdlib>
using namespace std;
 
int main()
{
    char strint[] = "137";
    char strfloat[] = "137.137";
    
    int i = atoi(strint);
    double f = atof(strfloat);
    
    cout << "int " << i << endl;
    cout << "float " << f << endl;
    
    return 0;
}

Реализации в С++ для atoi такая:

Код:
size_t _atoi(const char * str)
{
   size_t res = 0;
   for (; *str; res += *str++ - '0')
      res *= 10;
   return res;
}