Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

"Обнуление" структур и массивов

590
27 февраля 2008 года
Gigahard
223 / / 03.04.2006
Хотелось бы уточнить очередную мелочь... Соответствует ли стандарту обнуление структуры или массива при объявлении таким вот образом:
 
Код:
int iArr[10]={0};

struct COOLSTRUCT
{
    int a;
    char b;
};

COOLSTRUCT test={0};


Ведь по логике инициализации в таком случае должен инициализироватся только первый элемент массива, структуры...
Вот и возникло подозрение, что эта некая примочка то ли винды, то ли компилятора.
Собственно вопрос - гарантирует ли такой способ инициализации обнуление памяти? И соответствует ли он стандартам?

А то по старинке memset или ZeroMemory виндовую для обнуления использую...
3
27 февраля 2008 года
Green
4.8K / / 20.01.2000
Цитата: Gigahard
Хотелось бы уточнить очередную мелочь... Соответствует ли стандарту обнуление структуры или массива при объявлении таким вот образом:
 
Код:
int iArr[10]={0};

struct COOLSTRUCT
{
    int a;
    char b;
};

COOLSTRUCT test={0};


Ведь по логике инициализации в таком случае должен инициализироватся только первый элемент массива, структуры...
Вот и возникло подозрение, что эта некая примочка то ли винды, то ли компилятора.
Собственно вопрос - гарантирует ли такой способ инициализации обнуление памяти? И соответствует ли он стандартам?

А то по старинке memset или ZeroMemory виндовую для обнуления использую...


А почему бы самому не взять стандарт и не почитать?
Ответ: соответствует.

590
27 февраля 2008 года
Gigahard
223 / / 03.04.2006
А почему бы самому не взять стандарт и не почитать?
А смысл этого раздела на форуме?;) Я вот к примеру 3 справочника по С/С++ перерыл перед тем как этот вопрос задать. Так что моя совесть чиста :D
11
27 февраля 2008 года
oxotnik333
2.9K / / 03.08.2007
Цитата: Gigahard
Хотелось бы уточнить очередную мелочь... Соответствует ли стандарту обнуление структуры или массива при объявлении таким вот образом:
 
Код:
int iArr[10]={0};

struct COOLSTRUCT
{
    int a;
    char b;
};

COOLSTRUCT test={0};


Ведь по логике инициализации в таком случае должен инициализироватся только первый элемент массива, структуры...
Вот и возникло подозрение, что эта некая примочка то ли винды, то ли компилятора.
Собственно вопрос - гарантирует ли такой способ инициализации обнуление памяти? И соответствует ли он стандартам?

А то по старинке memset или ZeroMemory виндовую для обнуления использую...



COOLSTRUCT *test= NULL;

87
27 февраля 2008 года
Kogrom
2.7K / / 02.02.2008
Цитата: Green
А почему бы самому не взять стандарт и не почитать?
Ответ: соответствует.



Искал стандарт. Нашел это:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2461.pdf
и еще пару подобных ресурсов.

К сожалению, нигде не встретил способа, как инициализировать массив из нескольких значений одним числом (типа int iArr[10]={0};). И в учебниках не нашёл... Можете указать источник (и желательно страницу), в котором сказано об такой инициализации.

590
27 февраля 2008 года
Gigahard
223 / / 03.04.2006
[quote=oxotnik333]COOLSTRUCT *test= NULL;[/quote]
Вопрос был по инициализации статически создаваемой структуры.

[quote=Kogrom]К сожалению, нигде не встретил способа, как инициализировать массив из нескольких значений одним числом (типа int iArr[10]={0};). И в учебниках не нашёл... [/quote]
Аналогичная ситуация. По идее, такая запись должна инициализировать только первый элемент массива. С какой стати должны обнулятся остальные, не понятно.
3
27 февраля 2008 года
Green
4.8K / / 20.01.2000
Цитата: Kogrom
Искал стандарт. Нашел это:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2461.pdf
и еще пару подобных ресурсов.


Поиск "стандарт C++" по этому форуму дает несколько успешных находок.
Вот к примеру:
http://forum.codenet.ru/showthread.php?p=191393&highlight=%F1%F2%E0%ED%E4%E0%F0%F2+C#post191393

Цитата: Kogrom

К сожалению, нигде не встретил способа, как инициализировать массив из нескольких значений одним числом (типа int iArr[10]={0};). И в учебниках не нашёл... Можете указать источник (и желательно страницу), в котором сказано об такой инициализации.


В первом посте ты говорил об обнулении, а теперь уже об "инициализации одним числом". Аппетит приходит во время еды? :)

Источник - стандарт C++.

Цитата:

8.5.1 Aggregates

7 If there are fewer initializers in the list than there are members in the aggregate, then each member not explicitly initialized shall be value-initialized (8.5).
[Example:

struct S { int a; char* b; int c; };
S ss = { 1, "asdf" };

initializes ss.a with 1, ss.b with "asdf", and ss.c with the value of an expression of the form int(), that is, 0. ]


Исходя из этого, инициализировать дефолтовыми значениями можно даже так:
int iArr[10] = {};

87
27 февраля 2008 года
Kogrom
2.7K / / 02.02.2008
Цитата: Green
В первом посте ты говорил об обнулении, а теперь уже об "инициализации одним числом". Аппетит приходит во время еды? :)


У меня не было такого поста. Автор того поста другой человек. Наверно пора заводить аватарку...

Цитата: Green

Источник - стандарт C++.

...and ss.c with the value of an expression of the form int(), that is, 0...

Исходя из этого, инициализировать дефолтовыми значениями можно даже так:
int iArr[10] = {};


Тогда можно вобще не инициализаровать, все равно int по умолчанию будет нулём. И какой смысл в этой инициализации, если можно просто написать
int iArr[10];

590
27 февраля 2008 года
Gigahard
223 / / 03.04.2006
Да, это был я :)
Только не в курсе я, чем отличается обнуление при объявлении от инициализации...

Инициализировать то походу все же нужно, т.к. int нулем делает инициализация значением по умолчанию выражения int(), а не объявление...
 
Код:
struct noInit
{
    int a;
        char *b;
} tst;

int noInitArr[100];


Объявление всего лишь выделяет память нужного размера.

P.S. Пустой блок {} при инициализации не прокатывает :(...
276
27 февраля 2008 года
Rebbit
1.1K / / 01.08.2005
Цитата: Gigahard
Да, это был я :)
Только не в курсе я, чем отличается обнуление при объявлении от инициализации...


И я не в курсе. Может тем что для инициализации надо знать чем инициализировать, а для обнуления даже 0 не нужен. XOR по памяти и все. Угадал ?

1
27 февраля 2008 года
kot_
7.3K / / 20.01.2000
Цитата: Rebbit
И я не в курсе. Может тем что для инициализации надо знать чем инициализировать, а для обнуления даже 0 не нужен. XOR по памяти и все. Угадал ?


На сколько я знаю - есть термин "инициализация" - т.е. гарантированное присвоенное какого либо определенного значения какой либо вновь созданной переменной. "Обнуление" (если конечно такой термин существует :) ) - это гарантированная установка переменной в 0.

3
28 февраля 2008 года
Green
4.8K / / 20.01.2000
Цитата: kot_
На сколько я знаю - есть термин "инициализация" - т.е. гарантированное присвоенное какого либо определенного значения какой либо вновь созданной переменной.


+1

Цитата: kot_

"Обнуление" (если конечно такой термин существует :) ) - это гарантированная установка переменной в 0.


Такой термин применил кто-то из авторов вопроса.
На самом деле в этом контексте существует 3 термина:
zero-initialize,
default-initialize,
value-initialize
За подробностями следует обратиться к п.8.5 стандарта.

87
28 февраля 2008 года
Kogrom
2.7K / / 02.02.2008
Цитаты из стандарта
Цитата:

To zero-initialize an object of type T means:

if T is a scalar type (3.9), the object is set to the value 0 (zero), taken as an integral constant expression, converted to T;

if T is an array type, each element is zero-initialized;


и далее

Цитата:

Every object of static storage duration shall be zero-initialized at program startup before any other initialization takes place.


То есть, насколько я понял, если ничего не делать, то массив и проинициализируется нулём (zero-initialized). Значит, если просто записать
int iArr[10];
то, согласно стандарту, все элементы массива проинициализируются нулём. А колдовства с фигурными скобками в данном случае не требуется.

3
28 февраля 2008 года
Green
4.8K / / 20.01.2000
Цитата: Kogrom
Цитаты из стандарта

и далее

То есть, насколько я понял, если ничего не делать, то массив и проинициализируется нулём (zero-initialized). Значит, если просто записать
int iArr[10];
то, согласно стандарту, все элементы массива проинициализируются нулём. А колдовства с фигурными скобками в данном случае не требуется.


А где ты видишь в записи
int iArr[10];
инициализацию?
Инициализация описывается соотв. синтаксисом, см. п.п. 8.5.1 и 8.5.2

87
28 февраля 2008 года
Kogrom
2.7K / / 02.02.2008
Явно её нет, но меня смущает, то, что в стандарте я не нашел утверждения типа: если требуется произвести инициализацию нулем, следует записать выражение

тип имя_переменной[размер] = {};

Кроме того, меня смущает выражение:
Цитата:

Every object of static storage duration shall be zero-initialized at program startup before any other initialization takes place.


которое я понимаю так, что всякая переменная должна быть инициализирована нулем, до того, как будет иметь место любая другая инициализация. Но насколько я понимаю, массив нельзя инициализировать дважды, значит, происходит скрытая инициализация при объявлении.

Может это спорный вывод, но подтверждение ему я нашел только в примере

 
Код:
float y[4][3] = {
    { 1 }, { 2 }, { 3 }, { 4 }
};
initializes the first column of y (regarded as a two-dimensional array)
and leaves the rest zero.


Комментарий к примеру я понимаю примерно так: инициализируется первый столбец, все остальные элементы остаются в нуле. Заметьте, ОСТАЮТСЯ, а не устанавливаются в ноль. Хотя, может я неправильно перевожу.
3
28 февраля 2008 года
Green
4.8K / / 20.01.2000
Так тут вся тонкость в тех словах, которые ты почему-то упустил:
"Every object of static storage duration ..."

Читаем пункт 3.7.1 стандарта, и удивляемся коду:
Код:
#include <iostream>
using namespace std;

int globalArray[20];

int main()
{
    static int staticArray[20];
    int localArray[20];

    cout << "globalArray[2] = " << globalArray[2] << endl;
    cout << "staticArray[2] = " << staticArray[2] << endl;
    cout << "localArray[2] = "  << localArray[2]  << endl;

    return 0;
}

А чтобы не путаться, рекомендую всегда инициализировать явно с помощью инициализатора.
260
29 февраля 2008 года
Ramon
1.1K / / 16.08.2003
Код:
#include <iostream>
using namespace std;

int globalArray[20];

int main()
{
    static int staticArray[20];
    int localArray[20] = {};

    cout << "globalArray[2] = " << globalArray[2] << endl;
    cout << "staticArray[2] = " << staticArray[2] << endl;
    cout << "localArray[2] = "  << localArray[2]  << endl;

    return 0;
}


Продолжаем удивляться...???..., а ведь все это описано и не раз

PS: Что можно говорить о стандарте, если даже всем известную литературу не читали, хотя переведена она вполне сносно, и в принципе является стандартом в изложении "отца".

PS2:
 
Код:
int iVar;
int iVar2();

Так в чем же разница? Почему в языке сделано именно так? И почему статические объекты изначально забиты нулями? Постигнув принцип, уже не запутаешься.
3
29 февраля 2008 года
Green
4.8K / / 20.01.2000
Цитата: Ramon
Код:
#include <iostream>
using namespace std;

int globalArray[20];

int main()
{
    static int staticArray[20];
    int localArray[20] = {};

    cout << "globalArray[2] = " << globalArray[2] << endl;
    cout << "staticArray[2] = " << staticArray[2] << endl;
    cout << "localArray[2] = "  << localArray[2]  << endl;

    return 0;
}


Продолжаем удивляться...???..., а ведь все это описано и не раз

PS: Что можно говорить о стандарте, если даже всем известную литературу не читали, хотя переведена она вполне сносно, и в принципе является стандартом в изложении "отца".


Хм... это было адресовано мне?

Цитата: Ramon

PS2:
 
Код:
int iVar;
int iVar2();

Так в чем же разница? Почему в языке сделано именно так? И почему статические объекты изначально забиты нулями? Постигнув принцип, уже не запутаешься.


А при чем тут статические объекты?
int iVar; - определение переменной
int iVar2(); - объявление функции

260
29 февраля 2008 года
Ramon
1.1K / / 16.08.2003
Цитата: Green
Хм... это было адресовано мне?


А при чем тут статические объекты?
int iVar; - определение переменной
int iVar2(); - объявление функции



Адресовано не вам.

int iVar;
int iVar2();

это обе пременные типа int, с небольшим отличием, связанным с темой топика

3
29 февраля 2008 года
Green
4.8K / / 20.01.2000
Цитата: Ramon

int iVar;
int iVar2();

это обе пременные типа int, с небольшим отличием, связанным с темой топика


Ошибаешься. :)
Читаем "всем известную литературу".

260
29 февраля 2008 года
Ramon
1.1K / / 16.08.2003
Ошибаюсь, а может здесь не хватает контекста...
3
29 февраля 2008 года
Green
4.8K / / 20.01.2000
Цитата: Ramon
Ошибаюсь, а может здесь не хватает контекста...


Неа, просто ошибаешься, контекст здесь не при чем.
Смотрим "всем известную литературу":
[quote=Бьярн Страустрап. Справочное руководство по C++]
8.6 Инициализация

<skip>

Заметьте, что поскольку () не является инициализатором, то "X a();" является не описанием объекта класса X, а описанием функции, не получающей значений и возвращающей X.
[/quote]
[quote=INTERNATIONAL STANDARD ISO/IEC 14882 Second edition 2003-10-15]
8.5 Initializers

<skip>

8 [Note: since () is not permitted by the syntax for initializer,

X a();

is not the declaration of an object of class X, but the declaration of a function taking no argument and returning an X. The form () is permitted in certain other initialization contexts (5.3.4, 5.2.3, 12.6.2). ]
[/quote]

Наверное, ты имел в виду вот это:

int iVar2 = int();

87
29 февраля 2008 года
Kogrom
2.7K / / 02.02.2008
Цитата: Green
Так тут вся тонкость в тех словах, которые ты почему-то упустил:
"Every object of static storage duration ..."

Читаем пункт 3.7.1 стандарта, и удивляемся коду:
Код:
#include <iostream>
using namespace std;

int globalArray[20];

int main()
{
    static int staticArray[20];
    int localArray[20];

    cout << "globalArray[2] = " << globalArray[2] << endl;
    cout << "staticArray[2] = " << staticArray[2] << endl;
    cout << "localArray[2] = "  << localArray[2]  << endl;

    return 0;
}

А чтобы не путаться, рекомендую всегда инициализировать явно с помощью инициализатора.



Ну вот, теперь всё разложено по полочкам.
То есть, в приведенном примере для обнуления всех массивов достаточно записать

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

int globalArray[20];

int main()
{
    static int staticArray[20];
    int localArray[20] = {};

    cout << "globalArray[2] = " << globalArray[2] << endl;
    cout << "staticArray[2] = " << staticArray[2] << endl;
    cout << "localArray[2] = "  << localArray[2]  << endl;

    return 0;
}

А для единообразия все массивы можно инициализировать как localArray, хотя на работе программы это не должно отразиться.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог