Работа с объектами
JavaScript спроектирован на основе простой парадигмы. В основе концепции лежат простые объекты. Объект — это набор свойств, и каждое свойство состоит из имени и значения, ассоциированного с этим именем. Значением свойства может быть функция, которую можно назвать методом объекта. В дополнение к встроенным в браузер объектам, вы можете определить свои собственные объекты. Эта глава описывает как пользоваться объектами, свойствами, функциями и методами, а также как создавать свои собственные объекты.
Обзор объектов
Объекты в JavaScript, как и во многих других языках программирования, похожи на объекты реальной жизни. Концепцию объектов JavaScript легче понять, проводя параллели с реально существующими в жизни объектами.
В JavaScript объект — это самостоятельная единица, имеющая свойства и определённый тип. Сравним, например, с чашкой. У чашки есть цвет, форма, вес, материал, из которого она сделана, и т.д. Точно так же, объекты JavaScript имеют свойства, которые определяют их характеристики.
Объекты и свойства
В JavaScript объект имеет свойства, ассоциированные с ним. Свойство объекта можно понимать как переменную, закреплённую за объектом. Свойства объекта в сущности являются теми же самыми переменными JavaScript, за тем исключением, что они закреплены за объектом. Свойства объекта определяют его характеристики. Получить доступ к свойству объекта можно с помощью точечной записи:
.propertyName;
Как и все переменные JavaScript, имя объекта (которое тоже может быть переменной) и имя свойства являются чувствительными к регистру. Вы можете определить свойство указав его значение. Например, давайте создадим объект myCar и определим его свойства make , model , и year следующим образом:
var myCar = new Object(); myCar.make = "Ford"; myCar.model = "Mustang"; myCar.year = 1969;
Неопределённые свойства объекта являются undefined (а не null ).
.color; // undefined
Свойства объектов JavaScript также могут быть доступны или заданы с использованием скобочной записи (более подробно см. property accessors). Объекты иногда называются ассоциативными массивами, поскольку каждое свойство связано со строковым значением, которое можно использовать для доступа к нему. Так, например, вы можете получить доступ к свойствам объекта myCar следующим образом:
["make"] = "Ford"; myCar["model"] = "Mustang"; myCar["year"] = 1969;
Имена свойств объекта могут быть строками JavaScript, или тем, что может быть сконвертировано в строку, включая пустую строку. Как бы то ни было, доступ к любому имени свойства, которое содержит невалидный JavaScript идентификатор (например, имя свойства содержит в себе пробел и тире или начинается с цифры), может быть получен с использованием квадратных скобок. Этот способ записи также полезен, когда имена свойств должны быть динамически определены (когда имя свойства не определено до момента исполнения). Примеры далее:
var myObj = new Object(), str = "myString", rand = Math.random(), obj = new Object(); myObj.type = "Dot syntax"; myObj["date created"] = "String with space"; myObj[str] = "String value"; myObj[rand] = "Random Number"; myObj[obj] = "Object"; myObj[""] = "Even an empty string"; console.log(myObj);
Обратите внимание, что все ключи с квадратными скобками преобразуются в тип String, поскольку объекты в JavaScript могут иметь в качестве ключа только тип String. Например, в приведённом выше коде, когда ключ obj добавляется в myObj , JavaScript вызывает метод obj.toString () и использует эту результирующую строку в качестве нового ключа.
Вы также можете получить доступ к свойствам, используя значение строки, которое хранится в переменной:
var propertyName = "make"; myCar[propertyName] = "Ford"; propertyName = "model"; myCar[propertyName] = "Mustang";
Вы можете пользоваться квадратными скобками в конструкции for. in чтобы выполнить итерацию всех свойств объекта, для которых она разрешена. Чтобы показать как это работает, следующая функция показывает все свойства объекта, когда вы передаёте в неё сам объект и его имя как аргументы функции:
function showProps(obj, objName) var result = ""; for (var i in obj) if (obj.hasOwnProperty(i)) result += objName + "." + i + " token operator">+ obj[i] + "\n"; > > return result; >
Так что если вызвать эту функцию вот так showProps(myCar, «myCar»), то получим результат:
.make = Ford; myCar.model = Mustang; myCar.year = 1969;
Перечисление всех свойств объекта
Начиная с ECMAScript 5, есть три способа перечислить все свойства объекта (получить их список):
- циклы for. in (en-US) Этот метод перебирает все перечисляемые свойства объекта и его цепочку прототипов
- Object.keys(o) (en-US) Этот метод возвращает массив со всеми собственными (те, что в цепочке прототипов, не войдут в массив) именами перечисляемых свойств объекта o .
- Object.getOwnPropertyNames(o) (en-US) Этот метод возвращает массив содержащий все имена своих свойств (перечисляемых и неперечисляемых) объекта o .
До ECMAScript 5 не было встроенного способа перечислить все свойства объекта. Однако это можно сделать с помощью следующей функции:
function listAllProperties(o) var objectToInspect; var result = []; for ( objectToInspect = o; objectToInspect !== null; objectToInspect = Object.getPrototypeOf(objectToInspect) ) result = result.concat(Object.getOwnPropertyNames(objectToInspect)); > return result; >
Это может быть полезно для обнаружения скрытых (hidden) свойств (свойства в цепочке прототипа, которые недоступны через объект, в случае, если другое свойство имеет такое же имя в предыдущем звене из цепочки прототипа). Перечислить доступные свойства можно, если удалить дубликаты из массива.
Создание новых объектов
JavaScript содержит набор встроенных объектов. Также вы можете создавать свои объекты. Начиная с JavaScript 1.2, вы можете создавать объект с помощью инициализатора объекта. Другой способ — создать функцию-конструктор и сделать экземпляр объекта с помощью этой функции и оператора new .
Использование инициализаторов объекта
Помимо создания объектов с помощью функции-конструктора вы можете создавать объекты и другим, особым способом. Фактически, вы можете записать объект синтаксически, и он будет создан интерпретатором автоматически во время выполнения. Эта синтаксическая схема приведена ниже:
var obj = property_1: value_1, // property_# may be an identifier. 2: value_2, // or a number. // . "property n": value_n, >; // or a string
здесь obj — это имя нового объекта, каждое property_i — это идентификатор (имя, число или строковый литерал), и каждый value_i — это значения, назначенные property_i . Имя obj и ссылка объекта на него необязательна; если далее вам не надо будет ссылаться на данный объект, то вам не обязательно назначать объект переменной. (Обратите внимание, что вам потребуется обернуть литерал объекта в скобки, если объект находится в месте, где ожидается инструкция, чтобы интерпретатор не перепутал его с блоком.)
Если объект создан при помощи инициализатора объектов на высшем уровне скрипта, то JavaScript интерпретирует объект каждый раз, когда анализирует выражение, содержащее объект, записанный как литерал. Плюс, если пользоваться функцией инициализатором, то он будет создаваться каждый раз, когда функция вызывается.
Следующая инструкция создаёт объект и назначает его переменной x , когда выражение cond истинно.
if (cond) var x = hi: "there" >;
Следующий пример создаёт объект myHonda с тремя свойствами. Заметьте, что свойство engine — это также объект со своими собственными свойствами.
var myHonda = color: "red", wheels: 4, engine: cylinders: 4, size: 2.2, >, >;
Вы также можете использовать инициализатор объекта для создания массивов. Смотрите array literals.
До JavaScript 1.1 не было возможности пользоваться инициализаторами объекта. Единственный способ создавать объекты — это пользоваться функциями-конструкторами или функциями других объектов, предназначенных для этой цели. Смотрите Using a constructor function.
Использование функции конструктора
Другой способ создать объект в два шага описан ниже:
- Определите тип объекта, написав функцию-конструктор. Название такой функции, как правило, начинается с заглавной буквы.
- Создайте экземпляр объекта с помощью ключевого слова new .
Чтобы определить тип объекта создайте функцию, которая определяет тип объекта, его имя, свойства и методы. Например предположим, что вы хотите создать тип объекта для описания машин. Вы хотите, чтобы объект этого типа назывался car , и вы хотите, чтобы у него были свойства make, model, и year. Чтобы сделать это, напишите следующую функцию:
function Car(make, model, year) this.make = make; this.model = model; this.year = year; >
Заметьте, что используется this чтобы присвоить значения (переданные как аргументы функции) свойствам объекта.
Теперь вы можете создать объект, называемый mycar , следующим образом:
var mycar = new Car("Eagle", "Talon TSi", 1993);
Эта инструкция создаёт объект типа Car со ссылкой mycar и присваивает определённые значения его свойствам. Значением mycar.make станет строка «Eagle», mycar.year — это целое число 1993, и так далее.
Вы можете создать столько объектов car, сколько нужно, просто вызывая new . Например:
var kenscar = new Car("Nissan", "300ZX", 1992); var vpgscar = new Car("Mazda", "Miata", 1990);
Объект может иметь свойство, которое будет другим объектом. Например, далее определяется объект типа Person следующим образом:
function Person(name, age, sex) this.name = name; this.age = age; this.sex = sex; >
и затем создать два новых экземпляра объектов Person как показано далее:
var rand = new Person("Rand McKinnon", 33, "M"); var ken = new Person("Ken Jones", 39, "M");
Затем, вы можете переписать определение car и включить в него свойство owner , которому назначить объект person следующим образом:
function Car(make, model, year, owner) this.make = make; this.model = model; this.year = year; this.owner = owner; >
Затем, чтобы создать экземпляры новых объектов, выполните следующие инструкции:
var car1 = new Car("Eagle", "Talon TSi", 1993, rand); var car2 = new Car("Nissan", "300ZX", 1992, ken);
Заметьте, что вместо того, чтобы передавать строку, литерал или целое число при создании новых объектов, в выражениях выше передаются объекты rand и ken как аргумент функции. Теперь, если вам нужно узнать имя владельца car2, это можно сделать следующим образом:
.owner.name;
Заметьте, что в любое время вы можете добавить новое свойство ранее созданному объекту. Например, выражение
.color = "black";
добавляет свойство color к car1, и устанавливает его значение равным «black.» Как бы там ни было, это не влияет на любые другие объекты. Чтобы добавить новое свойство всем объектам одного типа, вы должны добавить свойство в определение типа объекта car .
Использование метода Object.create
Объекты также можно создавать с помощью метода Object.create . Этот метод очень удобен, так как позволяет вам указывать объект прототип для нового вашего объекта без определения функции конструктора.
// список свойств и методов для Animal var Animal = type: "Invertebrates", // Значение type по умолчанию displayType: function () // Метод отображающий тип объекта Animal console.log(this.type); >, >; // Создаём объект Animal var animal1 = Object.create(Animal); animal1.displayType(); // Выведет:Invertebrates // Создаём объект Animal и присваиваем ему type = Fishes var fish = Object.create(Animal); fish.type = "Fishes"; fish.displayType(); // Выведет:Fishes
Наследование
Все объекты в JavaScript наследуются как минимум от другого объекта. Объект, от которого произошло наследование называется прототипом, и унаследованные свойства могут быть найдены в объекте prototype конструктора.
Индексы свойств объекта
В JavaScript 1.0 вы можете сослаться на свойства объекта либо по его имени, либо по его порядковому индексу. В JavaScript 1.1 и позже, если вы изначально определили свойство по имени, вы всегда должны ссылаться на него по его имени, и если вы изначально определили свойство по индексу, то должны ссылаться на него по его индексу.
Это ограничение налагается когда вы создаёте объект и его свойства с помощью функции конструктора (как мы это делали ранее с типом Car ) и когда вы определяете индивидуальные свойства явно (например, myCar.color = «red» ). Если вы изначально определили свойство объекта через индекс, например myCar[5] = «25 mpg» , то впоследствии сослаться на это свойство можно только так myCar[5] .
Исключение из правил — объекты, отображаемые из HTML, например массив forms . Вы всегда можете сослаться на объекты в этих массивах или используя их индекс (который основывается на порядке появления в HTML документе), или по их именам (если таковые были определены). Например, если второй html-тег в документе имеет значение атрибута NAME равное «myForm», вы можете сослаться на эту форму вот так: document.forms[1] или document.forms[«myForm»] или document.myForm .
Определение свойств для типа объекта
Вы можете добавить свойство к ранее определённому типу объекта воспользовавшись специальным свойством prototype . Через prototype создаётся свойство, единое для всех объектов данного типа, а не одного экземпляра этого типа объекта. Следующий код демонстрирует это, добавляя свойство color ко всем объектам типа car , а затем присваивая значение свойству color объекта car1 .
Car.prototype.color = null; car1.color = "black";
Определение методов
Метод — это функция, ассоциированная с объектом или, проще говоря, метод — это свойство объекта, являющееся функцией. Методы определяются так же, как и обычные функции, за тем исключением, что они присваиваются свойству объекта. Например вот так:
.methodname = function_name; var myObj = myMethod: function (params) // . do something >, >;
где objectName — это существующий объект, methodname — это имя, которое вы присваиваете методу, и function_name — это имя самой функции.
Затем вы можете вызвать метод в контексте объекта следующим образом:
.methodname(params);
Вы можете определять методы для типа объекта, включая определение метода в функцию конструктора объекта. Например, вы можете определить функцию, которая форматирует и отображает свойства до этого определённых объектов car . Например,
function displayCar() var result = "A Beautiful " + this.year + " " + this.make + " " + this.model; pretty_print(result); >
где pretty_print — это функция отображения горизонтальной линии и строки. Заметьте, что использование this позволяет ссылаться на объект, которому принадлежит метод.
Вы можете сделать эту функцию методом car, добавив инструкцию
this.displayCar = displayCar;
к определению объекта. Таким образом, полное определение car примет следующий вид:
function Car(make, model, year, owner) this.make = make; this.model = model; this.year = year; this.owner = owner; this.displayCar = displayCar; >
Теперь вы можете вызвать метод displayCar для каждого из объектов как показано ниже:
.displayCar(); car2.displayCar();
Использование this для ссылки на объект
В JavaScript есть специальное ключевое слово this, которое вы можете использовать внутри метода, чтобы ссылаться на текущий объект. Предположим, у вас есть функция validate, которая сверяет свойство value, переданного ей объекта с некоторыми верхним и нижним значениями:
function validate(obj, lowval, hival) if (obj.value lowval || obj.value > hival) alert("Invalid Value!"); >
Вы можете вызвать эту функцию validate в каждом элементе формы, в обработчике события onchange . Используйте this для доступа к этому элементу, как это сделано ниже:
input type="text" name="age" size="3" onChange="validate(this, 18, 99)" />
В общем случае, this ссылается на объект, вызвавший метод.
Через this можно обратиться и к родительской форме элемента, воспользовавшись свойством form . В следующем примере форма myForm содержит элемент ввода Text и кнопку button1 . Когда пользователь нажимает кнопку, значению объекта Text назначается имя формы. Обработчик событий кнопки onclick пользуется this.form чтобы сослаться на текущую форму, myForm .
form name="myForm"> p> label>Form name:input type="text" name="text1" value="Beluga" />label> p> p> input name="button1" type="button" value="Show Form Name" onclick="this.form.text1.value = this.form.name" /> p> form>
Определение геттеров и сеттеров
Геттер(от англ. get — получить) — это метод, который получает значение определённого свойства. Сеттер (от англ. set — присвоить) — это метод, который присваивает значение определённому свойству объекта. Вы можете определить геттеры и сеттеры для любых из встроенных или определённых вами объектов, которые поддерживают добавление новых свойств. Синтаксис определения геттеров и сеттеров использует литеральный синтаксис объектов.
Ниже проиллюстрировано, как могут работать геттеры и сеттеры в объекте определённом пользователем:
var o = a: 7, get b() return this.a + 1; >, set c(x) this.a = x / 2; >, >; console.log(o.a); // 7 console.log(o.b); // 8 o.c = 50; console.log(o.a); // 25
Объект o получит следующие свойства:
- o.a — число
- o.b — геттер, который возвращает o.a плюс 1
- o.c — сеттер, который присваивает значение o.a половине значения которое передано в o.c
Следует особо отметить, что имена функций, указанные в литеральной форме «[gs]et propertyName() < >» не будут в действительности являться именами геттера и сеттера. Чтобы задать в качестве геттера и сеттера функции с явно определёнными именами, используйте метод Object.defineProperty (или его устаревший аналог Object.prototype.__defineGetter__ (en-US) ).
В коде ниже показано, как с помощью геттера и сеттера можно расширить прототип объекта Date и добавить ему свойство year, которое будет работать у всех экземпляров класса Date . Этот код использует существующие методы класса Date — getFullYear и setFullYear для работы геттера и сеттера.
Определение геттера и сеттера для свойства year :
var d = Date.prototype; Object.defineProperty(d, "year", get: function () return this.getFullYear(); >, set: function (y) this.setFullYear(y); >, >);
Использование свойства year заданного геттером и сеттером:
var now = new Date(); console.log(now.year); // 2000 now.year = 2001; // 987617605170 console.log(now); // Wed Apr 18 11:13:25 GMT-0700 (Pacific Daylight Time) 2001
В принципе, геттеры и сеттеры могут быть либо:
- определены при использовании Инициализаторов объекта, или
- добавлены существующему объекту в любой момент, при использовании методов добавления геттеров и сеттеров.
Когда определение геттера и сеттера использует инициализаторы объекта, всё что вам нужно, это дополнить геттер префиксом get а сеттер префиксом set . При этом, метод геттера не должен ожидать каких либо параметров, в то время как метод сеттера принимает один единственный параметр (новое значение для присвоения свойству). Например:
var o = a: 7, get b() return this.a + 1; >, set c(x) this.a = x / 2; >, >;
Геттеры и сеттеры, могут быть добавлены существующему объекту в любой момент, при помощи метода Object.defineProperties . Первый параметр этого метода — объект, которому вы хотите присвоить геттер и сеттер. Второй параметр — это объект, имена свойств которого будут соответствовать именам создаваемых свойств, а значения — объекты определяющие геттер и сеттер создаваемых свойств. В следующем примере создаются в точности такие же геттер и сеттер, как и в примере выше:
var o = a: 0 >; Object.defineProperties(o, b: get: function () return this.a + 1; >, >, c: set: function (x) this.a = x / 2; >, >, >); o.c = 10; // Запускает сеттер, который присваивает 10 / 2 (5) свойству 'a' console.log(o.b); // Запускает геттер, который возвращает a + 1 (тоесть 6)
То, какую из двух форм использовать для определения свойств, зависит от вашего стиля программирования и стоящей перед вами задачи. Если вы уже используете инициализатор объекта для определения прототипа, то, скорее всего, в большинстве случаев, вы воспользуетесь первой формой. Она более компактна и естественна. Однако, не редко, вторая форма является единственно возможной, в случаях, когда вы работаете с существующим объектом без доступа к его определению. Вторая форма наилучшим образом отражает динамическую природу JavaScript — но может сделать код сложным для чтения и понимания.
Удаление свойств
Вы можете удалить свойство используя оператор delete . Следующий код показывает как удалить свойство.
//Creates a new object, myobj, with two properties, a and b. var myobj = new Object(); myobj.a = 5; myobj.b = 12; //Removes the a property, leaving myobj with only the b property. delete myobj.a;
Вы также можете воспользоваться delete чтобы удалить глобальную переменную, если ключевое слово var не было использовано при её объявлении:
= 17; delete g;
Смотри [delete](Expressions_and_operators#delete) чтобы получить дополнительную информацию.
Сравнение объектов
В JavaScript объекты имеют ссылочный тип. Два отдельных объекта никогда не будут равными, даже если они имеют равный набор свойств. Только сравнение двух ссылок на один и тот же объект вернёт true.
// Две переменных ссылаются на два объекта с одинаковыми свойствами var fruit = name: "apple" >; var fruitbear = name: "apple" >; fruit == fruitbear; // вернёт false fruit === fruitbear; // вернёт false
// Две переменные ссылаются на один общий объект var fruit = name: "apple" >; var fruitbear = fruit; // присвоим переменной fruitbear ссылку на объект fruit // теперь fruitbear и fruit ссылаются на один и тот же объект fruit == fruitbear; // вернёт true fruit === fruitbear; // вернёт true
.name = "grape"; console.log(fruitbear); // вернёт < name: "grape" >вместо
Смотрите также
- Для детального изучения читайте подробнее об объектной модели JavaScript.
- Для изучения классов ECMAScript 2015 (новый способ определения объектов), читайте главу классы JavaScript.
- « Предыдущая статья
- Следующая статья »
Found a content problem with this page?
- Edit the page on GitHub.
- Report the content issue.
- View the source on GitHub.
This page was last modified on 7 авг. 2023 г. by MDN contributors.
Your blueprint for a better internet.
MDN
Support
- Product help
- Report an issue
Our communities
Developers
- Web Technologies
- Learn Web Development
- MDN Plus
- Hacks Blog
- Website Privacy Notice
- Cookies
- Legal
- Community Participation Guidelines
Visit Mozilla Corporation’s not-for-profit parent, the Mozilla Foundation.
Portions of this content are ©1998– 2023 by individual mozilla.org contributors. Content available under a Creative Commons license.
Как создать объект из строки c
Мы можем работать со строками в С++ в так называемом С-стиле как с массивами символов, которые оканчиваются на нулевой байт ‘0’. Однако, что если такой символ не будет найден или в процессе манипуляций со строкой будет удален, то дальшейшие действия с такой строкой могут иметь недетерминированный результат. По этой причине строки в С-стиле считаются небезопасными, и рекомендуется для хранения строк в C++ использовать тип std::string из модуля .
Объект типа string содержит последовательность символов типа char, которая может быть пустой. Например, определение пустой строки:
std::string message;
Также можно инициализировать или присвоить переменной string конкретную строку:
std::string message ; // или так std::string message2 = "Hello METANIT.COM!"; std::string message3("Hello METANIT.COM!");
В данном случае переменная message получит копию строкового литерала «Hello METANIT.COM!». В своем внутреннем представлении переменная message будет хранить массив символов, который также заканчивается на нулевой байт. Однако реализация типа string и предлагаемые им возможности делают работу с этим типом более безопасной.
И можно инициализировать объект string другим объектом string:
std::string hello; std::string message ; // message = "hello world" // или так // std::string message (hello); // std::string message = hello;
Мы можем вывести подобную строку на консоль:
#include #include int main() < std::string message ; std::cout
Получение и изменение символов строки
Подобно массиву мы можем обращаться с помощью индексов к отдельным символам строки, получать и изменять их:
std::string hello ; char c ; // e hello[0]='M'; std::coutПоскольку объект string представляет последовательность символов, то эту последовательность можно перебрать с помощью цикла for. Например, подсчитаем, сколько раз в строке встречается буква "l":
#include #include int main() < unsigned count<>; // счетчик, сколько раз встречается символ std::string message< "Hello World">; for(const char c: message) < if(c == 'l') < count++; >> std::coutЧтение строки с консоли
Для считывания введенной строки с консоли, как и для считывания других значений, можно использовать объект std::cin :
#include #include int main() < std::string name; std::cout > name; std::cout
Input your name: Tom Your name: TomОднако если при данном способе ввода строка будет содержать подстроки, разделенные пробелом, то std::cin будет использовать только первую подстроку:
Input your name: Tom Smith Your name: TomЧтобы считать всю строку, применяется метод getline() :
#include #include int main()
Метод getline принимает два объекта - std::cin и переменную, в которую надо считать строку.
Input your name: Tom Smith Your name: Tom Smith#19 – Создание классов и объектов
За урок вы на практике изучите использование классов и объектов. Вы познакомитесь с C++ ООП, научитесь строить классы и объекты на их основе.
Видеоурок
Создание классов
Для создания класса необходимо прописать ключевое слово class и далее название для класса. Общепринято начинать названия классов с буквы в верхнем регистре, но если этого не сделать, то ошибки не будет.
В любом классе можно создавать поля (переменные), методы (функции), а также конструкторы.
Создав новый класс и поместив туда какую-либо информацию мы можем создавать на основе него новые объекты. Объекты будут иметь доступ ко всем характеристикам класса, которые отмечены модификатором public .
Существует три модификатора доступа:
- public - данные будут видны повсюду, как в классе, так и вне его;
- protected - данные будут видны только в классе, где они были созданы, а также в классах наследниках;
- private - данные будут видны только в классе, где они были созданы.
Пример простого класса приведен ниже:
class Book < public: int pages; char name; float weight; void getInfoBook () < cout >;
На основе такого класса мы можем создать множество объектов. Каждый объект в данном случае будет представлять из себя конкретную книжку. Для каждого объекта мы можем указать уникальные данные: количество страниц, название книги и её вес.
Чтобы создать объект нам потребуется следующий код:
Book sherlock_holms; // Создание объекта sherlock_holms.getInfoBook(); // Вызов метода класса
Такой код можно прописать и в одной строке кода. Мы для наглядности разбили код в две строки.
Чтобы брать данные из класса через объект необходимо ставить точку и указывать имя переменной или функции, которую мы хотим взять.
Создание классов
#include #include using namespace std; class Building < private: int year; string type; public: void set_data(int y, string t) < year = y; type = t; >void get_info() < cout >; int main() < setlocale(LC_ALL, "RU"); Building school; //school.type = "Школа"; //school.year = 2000; school.set_data(2000, "Школа"); school.get_info(); Building house; //house.type = "Дом"; //house.year = 2010; house.set_data(2010, "Дом"); house.get_info(); return 0; >
Задание к уроку
Необходимо оформить подписку на проект, чтобы получить доступ ко всем домашним заданиям
Большое задание по курсу
Вам необходимо оформить подписку на сайте, чтобы иметь доступ ко всем большим заданиям. В задание входит методика решения, а также готовый проект с ответом к заданию.
PS: подобные задания доступны при подписке от 1 месяца
Строки в языке C
Строка -- это последовательность ASCII или UNICODE символов.
Строки в C, как и в большинстве языков программирования высокого уровня рассматриваются как отдельный тип, входящий в систему базовых типов языка. Так как язык C по своему происхождению является языком системного программирования, то строковый тип данных в C как таковой отсутствует, а в качестве строк в С используются обычные массивы символов.
Исторически сложилось два представления формата строк:
- формат ANSI;
- cтроки с завершающим нулем (используется в C).
Формат ANSI устанавливает, что значением первой позиции в строке является ее длина, а затем следуют сами символы строки. Например, представление строки "Моя строка!" будет следующим:
11 'М' 'о' 'я' ' ' 'с' 'т' 'р' 'о' 'к' 'а' '!'
В строках с завершающим нулем, значащие символы строки указываются с первой позиции, а признаком завершения строки является значение ноль. Представление рассмотренной ранее строки в этом формате имеет вид:
'М' 'о' 'я' ' ' 'с' 'т' 'р' 'о' 'к' 'а' '!' 0
Объявление строк в C
Строки реализуются посредством массивов символов. Поэтому объявление ASCII строки имеет следующий синтаксис:
char имя[длина];
Объявление строки в С имеет тот же синтаксис, что и объявление одномерного символьного массива. Длина строки должна представлять собой целочисленное значение (в стандарте C89 – константа, в стандарте C99 может быть выражением). Длина строки указывается с учетом одного символа на хранение завершающего нуля, поэтому максимальное количество значащих символов в строке на единицу меньше ее длины. Например, строка может содержать максимально двадцать символов, если объявлена следующим образом:
char str[21]; Инициализация строки в С осуществляется при ее объявлении, используя следующий синтаксис:
char str[длина] = строковый литерал;
Строковый литерал – строка ASCII символов заключенных в двойные кавычки. Примеры объявления строк с инициализацией:
char str1[20] = "Введите значение: ", str2[20] = "";
const char message[] = "Сообщение об ошибке!";
Работа со строками в С
Так как строки на языке С являются массивами символов, то к любому символу строки можно обратиться по его индексу. Для этого используется синтаксис обращения к элементу массива, поэтому первый символ в строке имеет индекс ноль. Например, в следующем фрагменте программы в строке str осуществляется замена всех символов 'a' на символы 'A' и наоборот.
for(int i = 0; str[i] != 0; i++)
if (str[i] == 'a') str[i] = 'A';
else if (str[i] == 'A') str[i] = 'a';
>
Массивы строк в С
Объявление массивов строк в языке С также возможно. Для этого используются двумерные массивы символов, что имеет следующий синтаксис:
char имя[количество][длина];
Первым размером матрицы указывается количество строк в массиве, а вторым – максимальная (с учетом завершающего нуля) длина каждой строки. Например, объявление массива из пяти строк максимальной длиной 30 значащих символов будет иметь вид:
При объявлении массивов строк можно производить инициализацию:
char имя[количество][длина] = ;
Число строковых литералов должно быть меньше или равно количеству строк в массиве. Если число строковых литералов меньше размера массива, то все остальные элементы инициализируются пустыми строками. Длина каждого строкового литерала должна быть строго меньше значения длины строки (для записи завершающего нуля).
char days[12][10] = <
"Январь", "Февраль", "Март", ”Апрель", "Май",
"Июнь", "Июль", "Август", "Сентябрь","Октябрь",
"Ноябрь", "Декабрь"
>;
При объявлении массивов строк с инициализацией допускается не указывать количество строк в квадратных скобках. В таком случае, количество строк в массиве будет определено автоматически по числу инициализирующих строковых литералов.
Например, массив из семи строк:
char days[][12] = <
"Понедельник", "Вторник", "Среда", "Четверг",
"Пятница", "Суббота", "Воскресенье"
>;
Функции для работы со строками в С
Все библиотечные функции, предназначенные для работы со строками, можно разделить на три группы:
- ввод и вывод строк;
- преобразование строк;
- обработка строк.
Ввод и вывод строк в С
Для ввода и вывода строковой информации можно использовать функции форматированного ввода и вывода (printf и scanf). Для этого в строке формата при вводе или выводе строковой переменной необходимо указать спецификатор типа %s. Например, ввод и последующий вывод строковой переменной будет иметь вид:
char str[31] = "";
printf("Введите строку: ");
scanf("%30s”,str);
printf("Вы ввели: %s”,str);
Недостатком функции scanf при вводе строковых данных является то, что символами разделителями данной функции являются:
- перевод строки,
- табуляция;
- пробел.
Поэтому, используя данную функцию невозможно ввести строку, содержащую несколько слов, разделенных пробелами или табуляциями. Например, если в предыдущей программе пользователь введет строку: "Сообщение из нескольких слов", то на экране будет выведено только "Сообщение".
Для ввода и вывода строк в библиотеке stdio.h содержатся специализированные функции gets и puts.
Функция gets предназначена для ввода строк и имеет следующий заголовок:
char * gets(char *buffer);
Между тем использовать функцию gets категорически не рекомендуется, ввиду того, что она не контролирует выход за границу строки, что может произвести к ошибкам. Вместо нее используется функция fgets с тремя параметрами:
char * fgets(char * buffer, int size, FILE * stream);
где buffer - строка для записи результата, size - максимальное количество байт, которое запишет функция fgets, stream - файловый объект для чтения данных, для чтения с клавиатуры нужно указать stdin. Эта функция читает символы со стандартного ввода, пока не считает n - 1 символ или символ конца строки, потом запишет считанные символы в строку и добавит нулевой символ. При этом функция fgets записывает в том символ конца строки в данную строку, что нужно учитывать.
Функция puts предназначена для вывода строк и имеет следующий заголовок:
int puts(const char *string);
Простейшая программа: ввод и вывод строки с использованием функций fgets и puts будет иметь вид:
char str[102] = "";
printf("Введите строку: ");
fgets(str, 102, stdin);
printf("Вы ввели: ");
puts(str);
Для считывания одного символа можно использовать функцию fgetc(FILE * stream) . Она считывает один символ и возвращает значение этого символа, преобразованное к типу int, если же считывание не удалось, то возвращается специальная константа EOF, равная -1. Функция возвращает значение -1 для того, чтобы можно было обрабатывать ситуацию конца файла, посимвольное чтение до конца файла можно реализовать следующим образом:
int c;
while ((c = fgetc(stdin)) != EOF) // Обработка символа
>
Для вывода одного символа можно использовать функцию int fputc(int c, FILE *stream); .
Помимо функций ввода и вывода в потоки в библиотеке stdio.h присутствуют функции форматированного ввода и вывода в строки. Функция форматированного ввода из строки имеет следующий заголовок:
int sscanf(const char * restrict buffer, const char * restrict string, [address] . );
Функции форматированного вывода в строку имеют следующие заголовки:
int sprintf(char * restrict buffer,
const char * restrict format, [argument] . );
int snprintf(char * restrict buffer, size_t maxsize,
const char * restrict format, [argument] . );
Преобразование строк
В С для преобразования строк, содержащих числа, в численные значения в библиотеке stdlib.h
предусмотрен следующий набор функций:
double atof(const char *string); // преобразование строки в число типа double
int atoi(const char *string); // преобразование строки в число типа int
long int atol(const char *string); // преобразование строки в число типа long int
long long int atoll(const char *string); // преобразование строки в число типа long long int
Корректное представление вещественного числа в текстовой строке должно удовлетворять формату:
После символов E, e указывается порядок числа. Корректное представление целого числа в текстовой строке должно удовлетворять формату:
Помимо приведенных выше функций в библиотеке stdlib.h доступны также следующие функции преобразования строк в вещественные числа:
float strtof(const char * restrict string, char ** restrict endptr);
double strtod(const char * restrict string, char ** restrict endptr);
long double strtold(const char * restrict string,char ** restrict endptr);
Аналогичные функции присутствуют и для преобразования строк в целочисленные значения:
long int strtol(const char * restrict string, char ** restrict endptr, int base);
unsigned long strtoul(const char * restrict string,
char ** restrict endptr, int base);
long long int strtoll(const char * restrict string,
char ** restrict endptr, int base);
unsigned long long strtoull(const char * restrict string,char ** restrict endptr, int base);
Функции обратного преобразования (численные значения в строки) в библиотеке stdlib.h присутствуют, но они не регламентированы стандартом, и рассматриваться не будут. Для преобразования численных значений в строковые наиболее удобно использовать функции sprintf и snprintf.
Обработка строк
В библиотеке string.h содержаться функции для различных действий над строками.
Функция вычисления длины строки:
size_t strlen(const char *string);
char str[] = "1234";
int n = strlen(str); //n == 4
Функции копирования строк:
char * strcpy(char * restrict dst, const char * restrict src);
char * strncpy(char * restrict dst, const char * restrict src, size_t num);
Функции сравнения строк:
int strcmp(const char *string1, const char *string2);
int strncmp(const char *string1, const char *string2,size_t num);
Функции осуществляют сравнение строк по алфавиту и возвращают:
положительное значение – если string1 больше string2;
отрицательное значение – если string1 меньше string2;
нулевое значение – если string1 совпадает с string2;
Функции объединения (конкатенации) строк:
char * strcat(char * restrict dst, const char * restrict src);
char * strncat(char * restrict dst, const char * restrict src, size_t num);
Функции поиска символа в строке:
char * strchr(const char *string, int c);
char * strrchr(const char *string, int c);
Функция поиска строки в строке:
char * strstr(const char *str, const char *substr);
char str[] = "Строка для поиска";
char *str1 = strstr(str,"для"); //str1 == "для поиска"
Функция поиска первого символа в строке из заданного набора символов:
size_t strcspn(const char *str, const char *charset);
Функции поиска первого символа в строке не принадлежащему заданному набору символов:
size_t strspn(const char *str, const char *charset);
Функции поиска первого символа в строке из заданного набора символов:
char * strpbrk(const char *str, const char *charset);
Функция поиска следующего литерала в строке:
char * strtok(char * restrict string, const char * restrict charset);
