чем отличается присваивание от инициализации?
Оставим, так сказать, за кадром массу проблем в вашем коде. Отличие в том, что во втором случае сначала создается «пустой» объект, а затем выполняется присваивание, а в первом — сразу создается нужный объект.
18 фев в 14:55
2 ответа 2
Сортировка: Сброс на вариант по умолчанию
Инициализация происходит один раз при вызове конструктора, присвоение — каждый раз при вызове оператора = .
На строке sample ob = input(); происходит инициализация (с использованием нежелательного синтаксиса copy initialization). Вместо этого во всех случаях следует использовать синтаксис direct list initialization sample ob; .
На строке ob = input(); происходит присваивание. Оно заканчивается плохо, так как оператор = для класса не переопределен надлежащим образом для корректного обращения с динамически выделенной памятью. Для любых не POD классов оператор = следует либо определять, либо запрещать. см правило 0/3/5
Отслеживать
ответ дан 18 фев в 15:10
user7860670 user7860670
29.6k 3 3 золотых знака 17 17 серебряных знаков 36 36 бронзовых знаков
Функция присваивания подразумевает аккуратно избавляться от текущего состояния объекта и присваивания нового.
Так как вы сами написали конструктор копирования, то оператор присваивания по-умолчанию не будет реалезован и вы должны сами его написать.
А-ля :
sample & sample :: operator = ( sample const & obj ) < // здесь и присутствует отличие от конструктора delete [ ] s ; s = new char[strlen(obj.s) + 1]; strcpy_s(s, strlen(obj.s) + 1, obj.s); cout
плохую функцию set можете удалить.
Отслеживать
ответ дан 18 фев в 19:19
17.1k 1 1 золотой знак 9 9 серебряных знаков 33 33 бронзовых знака
- c++
- функции
- перегрузка-операторов
- return
-
Важное на Мете
Похожие
Подписаться на ленту
Лента вопроса
Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.
Дизайн сайта / логотип © 2023 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2023.11.21.1314
Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.
Чем инициализация отличается от присваивания
Инициализация, присваивание и объявление переменной в Си, ошибки
Правильная инициализация переменной в С имеет важное значение. Потому что если ее сделать некорректно, тогда программа на С будет работать с ошибками или вообще не будет работать. Поэтому сегодня в статье поговорим о переменных в С.
Напомним, переменная — это имя «куска памяти», который будет временно сохранять какую-то информацию. Работа переменных тесно связана с оперативной памятью устройства. Когда мы объявляем переменную в коде, то, фактически, мы говорим компилятору в устройстве: «выдели немного оперативной памяти вот для такого-то значения». Если в момент объявления переменной сделать какую-то ошибку, тогда может возникнуть проблема с оперативной памятью. Допустим, выделится недостаточное количество памяти или, наоборот, переменная у потребит слишком много памяти и др.
Инициализация переменной в С
Почему важна правильная инициализация переменной в С? Любая информация, которая попадает внутрь компьютер а, преобразуется в последовательность битов. Бит — это минимальное значение в памяти, которое может быть двух значений: «0» или «1». Если рассмотреть какой-то «кусок памяти» в компьютере, тогда можно увидет ь, что он похож на нечто такое: «010110110011001110100110».
Когда мы объявляем переменную, мы просим выделить ей какое-то количество памяти. Однако мы не указываем необходимое количество памяти в битах, а указываем тип переменной. Компилятор самостоятельно определяет сколько и каким образом нужно выделить памят и для вашей переменной, основываясь на ее типе.
Инициализация переменной в С — это объявление ее типа и одновременное присвоение ей значения. Таким образом, для разработчика важно определить к какому типу данных относится его переменная, а обо всем остальном заботятся компилятор и процессор.
Основные типы переменных в С
- размер выделенной памяти зависит от типа переменной;
- представление переменной в памят и также зависит от типа переменной.
- «char» с размером 1 байт;
- «short» с размером 2 байта;
- «int» с размером 4 байта;
- «long» с размером 4 байта;
- «long long» с размером 8 байт.
- «float» с размером в 4 байта;
- «long float» с размером в 8 байт;
- «double» с размером в 8 байт;
- «long double» с размером в 8 байт.
Как происходит объявление, присвоение и инициализация переменной в С
- тип переменной;
- имя переменной.
- «Копирующая инициализация». Происходит при помощи знака «равно» и выглядит вот так: «int myVar = 7».
- «Прямая инициализация». Происходит при помощи «круглых скобок» и выглядит вот так: «int myVar(7);».
Заключение
Сегодня мы познакомились с особенностями переменных в языке программирования С. В частности, вы могли увидеть как проходит объявление, присвоение и инициализация переменной в С.
При работе с переменными в С, нужно обязательно запомнить, что определение их типа имеет ключевое значение.
Мы будем очень благодарны
если под понравившемся материалом Вы нажмёте одну из кнопок социальных сетей и поделитесь с друзьями.
C++/Operations
Операции в C++ — всевозможные действия, что допустимы в языке программирования.
Объявление переменных
Объявить целочисленную переменную:
где int — тип, а nVar — имя переменной.
Принцип объявления переменных разных типов аналогичен:
где type — тип (напр., int ), а varNm — имя переменной.
Объявление пяти переменных разных типов:
Переменной типа void быть не может:
не будет работать, так как void не может использоваться в качестве типа переменной.
Инициализация переменных
При объявлении переменной можно сразу присвоить ей значение. Это называется инициализацией переменной. Важно понимать разницу, это не присваивание переменной значения, а именно инициализация переменной значением.
Язык C++ поддерживает 2 основных способа инициализации переменных.
- Копирующая инициализация (или «инициализация копированием») с помощью знака равенства = :
- Прямая инициализация с помощью круглых скобок () :
Прямая инициализация лучше работает с одними типами данных, копирующая инициализация — с другими.
uniform-инициализация переменных
Прямая или копирующая инициализация работают не со всеми типами данных (напр., нельзя использовать эти способы для инициализации списка значений). В попытке обеспечить единый механизм инициализации, который будет работать со всеми типами данных, в C++11 добавили новый способ инициализации, который называется uniform-инициализация: Инициализация переменной с пустыми фигурными скобками указывает на инициализацию по-умолчанию (переменной присваивается 0): В uniform-инициализации есть еще одно дополнительное преимущество: нельзя присвоить переменной значение, которое не поддерживает её тип данных — компилятор выдаст предупреждение или сообщение об ошибке. Например:
Присваивание значений переменным
Когда переменной задаётся значение после её объявления (не в момент объявления), то это не инициализация, а присваивание (оно же «копирующее присваивание»). Присваивание переменной значения: Инициализация и присваивание это разные операции, несмотря на то, что обозначаются одним знаком ( = ). Присваивание уничтожает предыдущее значение, а инициализация ничего не уничтожает. В языке C++ нет встроенной поддержки способов прямого/uniform-присваивания, есть только копирующее присваивание.
Объявление и инициализация нескольких переменных
Синтаксис C++ допускает указание переменных через запятую. Т.е. в одном стейтменте можно по очереди объявить и инициализировать сразу несколько переменных одного и того же типа данных, разделяя их имена запятыми. В заголовке функции так делать нельзя.
Объявление нескольких переменных
Можно один раз указать тип, а имена переменных перечислить через запятую. Например, следующие 2 фрагмента кода выполняют одно и то же:
Инициализация нескольких переменных
Можно инициализировать несколько переменных в одном стейтменте: В C++11 добавили uniform-инициализацию и для расширенного списка инициализаторов (extended initializer list): Определять каждую переменную в очереди не обязательно, можно и вполне достаточно просто объявить её и всё: Сразу тут же можно инициализировать одну переменную значением другой, которая уже была инициализирована: Можно чередовать и комбинировать способы инициализации, и инициализировать одну переменную значением другой, которая была инициализирована другим способом:
Ошибки
- Указание каждой переменной одного и того же типа данных при инициализации нескольких переменных в одном стейтменте. Это не критичная ошибка, так как компилятор легко её обнаружит и сообщит об этом:
- Использование разных типов данных в одном стейтменте. Переменные разных типов должны быть объявлены в разных стейтментах. Эту ошибку компилятор также легко обнаружит:
- Инициализация двух переменных с помощью одной операции:
Избегайте объявления нескольких переменных в одной строке, если не собираетесь инициализировать каждую из них.
Похожие публикации:
- Сколько вариантов пароля из 4 цифр
- Спеки что это в компьютере
- Срок действия этого сертификата уже истек или еще не наступил что делать
- Стиральная машина индезит ошибка f02 что делать
В чем разница между инициализацией и присваиванием в Си++?
Инициализация - присваивание объявленной переменной первого значения. Все последующие присваивания будут изменять предыдущие значения.
Остальные ответы
тут подробнейше описано об присвоении и инициализации
Одно без другого - бессмысленно.
Инициализация - выделение ячейки памяти с меткой, присвоение - запись туда значения
int i; // это инициализация
i = 5; // это присвоение
может быть одновременное
int i = 5;
int i; // это объявление
int i = 5; // это инициализация
i=5; // это присвоение
Аня ТкаченкоУченик (246) 6 лет назад
Лучший и лаконичный ответ, мне помогли спасибо :)
Похожие вопросы
Ваш браузер устарел
Мы постоянно добавляем новый функционал в основной интерфейс проекта. К сожалению, старые браузеры не в состоянии качественно работать с современными программными продуктами. Для корректной работы используйте последние версии браузеров Chrome, Mozilla Firefox, Opera, Microsoft Edge или установите браузер Atom.
1.4 – Присваивание и инициализация переменных
В предыдущем уроке «1.3 – Знакомство с переменными в C++» мы рассмотрели, как определить переменную, которую мы сможем использовать для хранения значений. В этом уроке мы узнаем, как помещать значения в переменные, и как использовать эти значения.
Напоминаем, что следующий короткий фрагмент сначала выделяет память для одной целочисленной переменной с именем x , а затем выделяет память еще для двух целочисленных переменных с именами y и z :
int x; // определяем целочисленную переменную с именем x int y, z; // определяем две целочисленные переменные с именами y и z
Присваивание значения переменной
После того, как переменная была определена, вы можете присвоить ей значение (в отдельной инструкции) с помощью оператора = . Этот процесс для краткости называется копирующим присваиванием (или просто присваиванием).
int width; // определяем целочисленную переменную с именем width width = 5; // копирующее присваивание значения 5 в переменную width // переменная width теперь имеет значение 5
Копирующее присваивание названо так, потому что оно копирует значение с правой стороны оператора = в переменную с левой стороны оператора. Оператор = называется оператором присваивания.
Вот пример, где мы используем присваивание дважды:
#include int main() < int width; width = 5; // копирующее присваивание значения 5 в переменную width // переменная width теперь имеет значение 5 width = 7; // изменить значение, сохраненное в переменной width, на 7 // переменная width теперь имеет значение 7 return 0; >
Когда мы присваиваем значение 7 переменной width , значение 5, которое было там ранее, перезаписывается. Обычные переменные могут содержать только одно значение за раз.
Предупреждение
Одна из наиболее распространенных ошибок, которые делают новички, – это путать оператор присваивания ( = ) с оператором равенства ( == ). Присваивание ( = ) используется для присвоения значения переменной. Равенство ( == ) используется для проверки того, равны ли два операнда по значению.
Копирующая и прямая инициализации
Одним из недостатков присваивания является то, что для него требуются как минимум две инструкции: одна для определения переменной, а другая для присвоения значения.
Эти два шага можно совместить. При определении переменной вы также можете одновременно указать для нее начальное значение. Это называется инициализацией.
C++ поддерживает три основных способа инициализации переменных. Во-первых, мы можем выполнить копирующую инициализацию, используя знак равенства:
int width = 5; // копирующая инициализация значения 5 в переменную width
Подобно копирующему присваиванию, этот код копирует значение с правой стороны знака равно в переменную, создаваемую с левой стороны.
Во-вторых, мы можем выполнить прямую инициализацию с помощью скобок.
int width(5); // прямая инициализация значения 5 в переменную width
Для простых типов данных (например, целых чисел) копирующая и прямая инициализации, по сути, одинаковы. Различия между копирующей инициализацией и прямой инициализацией мы увидим в этой серии статей позже.
В-третьих, инициализация списком, которую мы рассмотрим в следующем разделе.
Инициализации списком
К сожалению, прямая инициализация с круглыми скобками не может использоваться для всех типов инициализации (таких как инициализация объекта списком данных). Чтобы обеспечить более согласованный механизм инициализации, существует инициализация списком (также иногда называемая унифицированной инициализацией или инициализацией с фигурными скобками), в которой используются фигурные скобки.
Инициализация списком бывает двух форм:
int width; // прямая инициализация списком значения 5 в переменную width (предпочтительно) int height = ; // копирующая инициализация списком значения 6 в переменную height
Эти две формы функционируют почти одинаково, но обычно предпочтительнее прямая форма.
Инициализация переменной с пустыми фигурными скобками указывает на инициализацию значения. В большинстве случаев инициализация значения инициализирует переменную нулевым значением (или пустым, если это более подходит для данного типа). В таких случаях, когда происходит обнуление, инициализация значения также называется нулевой инициализацией.
int width<>; // инициализация значения значением 0
Инициализация списком имеет дополнительное преимущество, так как запрещает «сужающие» преобразования. Это означает, что если вы попытаетесь использовать инициализацию списком для инициализации переменной значением, которое она не может безопасно удерживать, компилятор выдаст предупреждение или ошибку. Например:
int width; // ошибка: не все значения типа double помещаются в int
В приведенном выше фрагменте мы пытаемся присвоить число ( 4.5 ), имеющее дробную часть (часть .5 ), целочисленной переменной (которая может содержать только числа без дробных частей). При копирующей и прямой инициализациях дробная часть будет отброшена, что приведет к инициализации переменной width значением 4. Однако при инициализации списком это приведет к тому, что компилятор выдаст ошибку (что, как правило, хорошо потому, что потеря данных редко бывает желательной). Преобразования, которые могут быть выполнены без потенциальной потери данных, в этом случае разрешены.
Лучшая практика
По возможности отдавайте предпочтение прямой инициализации списком.
Вопрос: C++ обеспечивает копирующую, прямую инициализации и инициализацию списком, а также копирующее присваивание. Существует ли прямое присваивание или присваивание списком?
Нет, C++ не поддерживает синтаксис прямого присваивания или присваивания списком.
Вопрос: Когда следует инициализировать с помощью , а когда с помощью <> ?
Используйте явную инициализацию значением, если вы действительно используете это значение.
int x; // явная инициализация значением 0 std::cout
Используйте инициализацию значения, если значение временное и будет заменено.
int x<>; // инициализация значения std::cin >> x; // мы немедленно заменяем это значение
Инициализируйте свои переменные
Инициализируйте свои переменные при создании. В конечном итоге вам могут встретиться случаи, когда вы захотите проигнорировать этот совет по определенной причине (например, критический для производительности фрагмент кода, который использует множество переменных), и это нормально, если выбор сделан сознательно.
Для более подробного обсуждения этой темы Бьёрн Страуструп (создатель C++) и Герб Саттер (эксперт по C ++) сами дают рекомендацию здесь.
Мы исследуем, что произойдет, если вы попытаетесь использовать переменную, для которой нет четко определенного значения, в уроке «1.6 – Неинициализированные переменные и неопределенное поведение».
Лучшая практика
Инициализируйте свои переменные при создании.
Инициализация нескольких переменных
В последнем разделе мы отметили, что можно определить несколько переменных одного типа в одной инструкции, разделив имена запятыми:
int a, b;
Мы также отметили, что лучше всего вообще избегать этого синтаксиса. Однако, поскольку вы можете столкнуться с чужим кодом, использующим этот стиль, всё же полезно поговорить об этом немного подробнее хотя бы, чтобы акцентировать внимание на некоторых причинам, по которым вам следует избегать его.
Вы можете инициализировать несколько переменных, определенных в одной строке:
int a = 5, b = 6; // копирующая инициализация int c(7), d(8); // прямая инициализация int e, f; // инициализация списком (предпочтительно)
К сожалению, здесь есть распространенная ошибка, которая может возникнуть, когда программист по ошибке пытается инициализировать обе переменные с помощью одной инструкции инициализации:
int a, b = 5; // неверно (a не инициализируется!) int a = 5, b = 5; // верно
В верхней инструкции переменная a будет оставлена неинициализированной, и компилятор может пожаловаться, а может и не пожаловаться. Если он не пожалуется, это отличный способ для вашей программы периодически давать сбои и выдавать случайные результаты. В ближайшее время мы подробнее поговорим о том, что произойдет, если вы будете использовать неинициализированные переменные.
Лучший способ запомнить, что это неправильно, – рассмотреть случай прямой инициализации или инициализации списком:
int a, b(5); int c, d;
Этот код делает более ясным, что значение 5 используется только для инициализации переменной b или d , а не a или c .
Небольшой тест
Вопрос 1
В чем разница между инициализацией и присваиванием?
Инициализация дает переменной начальное значение в момент ее создания. Присваивание дает переменной значение в какой-то момент после создания.
Вопрос 2
Какую форму инициализации следует использовать?
Прямая инициализация списком.
