Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

инициализация массива ссылок

19 views
Skip to first unread message

Valera Kolesnik

unread,
Nov 27, 2007, 4:17:37 AM11/27/07
to
Hello everybody.

читаю Керниган, Ричи. возник вопрос:
можно проинициализировать
static char *name[] = {"jan", "feb"};

как также проинициализировать
static int *v[]?

неужели только так:
static int v1[] = {1, 2, 3};
static int v2[] = {7};
static int v3[] = {5, 5};
static int *v[] = {v1, v2, v3};

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

и ещё. отличаются ли чем
int *p;
от
int* p;

Valera

Dmitry E. Oboukhov

unread,
Nov 27, 2007, 12:58:43 PM11/27/07
to
VK> как также проинициализировать
VK> static int *v[]?

VK> неужели только так:
VK> static int v1[] = {1, 2, 3};
VK> static int v2[] = {7};
VK> static int v3[] = {5, 5};
VK> static int *v[] = {v1, v2, v3};

VK> ведь должен же быть способ покороче и без множества ненужных имён для
VK> временных массивов.
а int *v[]={{1,2,3},{3,4,5},{6,7,8}};
уже не работает?
сорри я не слежу за С, давно не нужен был

... Либерализм - затыкание ртов под вопли о свободе слова.

Valera Kolesnik

unread,
Nov 27, 2007, 7:06:30 AM11/27/07
to
Hello Dmitry.

27 Nov 07 20:58, you wrote to me:

VK>> как также проинициализировать
VK>> static int *v[]?

VK>> неужели только так:
VK>> static int v1[] = {1, 2, 3};
VK>> static int v2[] = {7};
VK>> static int v3[] = {5, 5};
VK>> static int *v[] = {v1, v2, v3};

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

DO> а int *v[]={{1,2,3},{3,4,5},{6,7,8}};
DO> уже не работает?
в том-то и дело, что ругается:
warning: braces around scalar initializer
warning: (near initialization for `v[0]')
warning: initialization makes pointer from integer without a cast
warning: excess elements in scalar initializer
warning: (near initialization for `v[0]')
warning: excess elements in scalar initializer
warning: (near initialization for `v[0]')
warning: braces around scalar initializer
warning: (near initialization for `v[1]')

попутно
char c[] = "one";
char b[] = {'o', 'n', 'e', '\0'};
аналоги.

но вот только такое принимается:
char *a[] = {c, "two", b};
а сделанное по аналогии (как для обычных массивов):
char *a[] = {c, {'t', 'w', 'o', '\0'}, b};
уже нет.
или я что-то недопонимаю, или где логика?

Valera

Alex Mogilnikov

unread,
Nov 27, 2007, 7:12:39 PM11/27/07
to
Привет Valera!

27 Nov 07 15:06, Valera Kolesnik писал Dmitry E. Oboukhov:

VK> попутно
VK> char c[] = "one";
VK> char b[] = {'o', 'n', 'e', '\0'};
VK> аналоги.

VK> но вот только такое принимается:
VK> char *a[] = {c, "two", b};
VK> а сделанное по аналогии (как для обычных массивов):
VK> char *a[] = {c, {'t', 'w', 'o', '\0'}, b};
VK> уже нет.
VK> или я что-то недопонимаю, или где логика?

Логика, как обычно, в правилах языка. Пункт 6.5.2.5:

Semantics

[#4] A postfix expression that consists of a parenthesized
^^^^^^^^^^^^^
type name followed by a brace-enclosed list of initializers
^^^^^^^^^
is a compound literal.

Соответственно, вставив недостающее, получаем:

char *a[] = {c, (char []){'t', 'w', 'o', '\0'}, b};

Всего наилучшего, [Team PCAD 2000]
Алексей М.
... Старый глюк лучше новых двух...

Valera Kolesnik

unread,
Nov 27, 2007, 1:11:26 PM11/27/07
to
Hello Alex.

28 Nov 07 03:12, you wrote to me:

VK>> или я что-то недопонимаю, или где логика?

AM> Логика, как обычно, в правилах языка. Пункт 6.5.2.5:

AM> Semantics

AM> [#4] A postfix expression that consists of a parenthesized
AM> ^^^^^^^^^^^^^
AM> type name followed by a brace-enclosed list of initializers
AM> ^^^^^^^^^
AM> is a compound literal.

AM> Соответственно, вставив недостающее, получаем:

AM> char *a[] = {c, (char []){'t', 'w', 'o', '\0'}, b};
ого! спасибо, действительно работает. для строк и просто массивов. однако, если
в
static int v1[] = {5, 3, 1};
static int v2[] = {1, 2};
int *s[] = {v1, v2, (int []){8, 3}};
последнюю строчку изменить на:
static int *s[] = {v1, v2, (int []){8, 3}};
то ругается:
error: initializer element is not constant.
как быть?

Valera

Alex Mogilnikov

unread,
Nov 28, 2007, 5:38:41 AM11/28/07
to
Привет Valera!

27 Nov 07 21:11, Valera Kolesnik писал Alex Mogilnikov:

AM>> char *a[] = {c, (char []){'t', 'w', 'o', '\0'}, b};

VK> ого! спасибо, действительно работает. для строк и просто массивов.
VK> однако, если в static int v1[] = {5, 3, 1}; static int v2[] = {1, 2};
VK> int *s[] = {v1, v2, (int []){8, 3}}; последнюю строчку изменить
VK> на: static int *s[] = {v1, v2, (int []){8, 3}}; то ругается:
VK> error: initializer element is not constant.
VK> как быть?

Прочитать, наконец, правила языка. В том же п. 6.5.2.5 двумя абзацами ниже
приведенного мной отрывка описано, когда какой storage class имеет объект,
создаваемый compound literal (извини, не знаю, как это правильно назвать
по-русски).

Всего наилучшего, [Team PCAD 2000]
Алексей М.

... Слепой Пью, Глухой Ем...

Valera Kolesnik

unread,
Nov 28, 2007, 4:28:44 AM11/28/07
to
Hello Alex.

28 Nov 07 13:38, you wrote to me:

AM>>> char *a[] = {c, (char []){'t', 'w', 'o', '\0'}, b};
VK>> ого! спасибо, действительно работает. для строк и просто массивов.
VK>> однако, если в static int v1[] = {5, 3, 1}; static int v2[] = {1, 2};
VK>> int *s[] = {v1, v2, (int []){8, 3}}; последнюю строчку изменить
VK>> на: static int *s[] = {v1, v2, (int []){8, 3}}; то ругается:
VK>> error: initializer element is not constant.
VK>> как быть?

AM> Прочитать, наконец, правила языка. В том же п. 6.5.2.5 двумя абзацами
AM> ниже приведенного мной
AM> отрывка описано, когда какой storage class имеет объект, создаваемый
AM> compound literal (извини, не
AM> знаю, как это правильно назвать по-русски).
где их брать, эти правила?
я ж C только изучаю. не ожидал такого подвоха от кернигана и ричи в простом,
казалось бы, задании - перепишите ... используя вместо индексации указатели.

Valera

Andrey Tarasevich

unread,
Nov 28, 2007, 2:41:27 PM11/28/07
to
Tue Nov 27 2007 12:17, Valera Kolesnik wrote to All:

VK> читаю Керниган, Ричи.

Т.е. речь идет о С, а не о С++. Тогда не рекомендую запутывать народ,
употребляя термин "ссылка" в вопросе о С, заданном в С++ конфе.

VK> возник вопрос:
VK> можно проинициализировать
VK> static char *name[] = {"jan", "feb"};

VK> как также проинициализировать
VK> static int *v[]?

В "традиционном" C (ANSI C89/90) - никак, так как "массивные" литералы в нем
есть только для строк (как в примере выше). Для массивов 'int' литералов нет.

В "новом" же ANSI С99 есть литералы для любых массивов, поэтому там это можно
сделать так

static int *v[] = {
(int[]) { 1, 2, 3 },
(int[]) { 7 },
(int[]) { 5, 5 }
};

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

В ANSI C89/90 - нет.

VK> и ещё. отличаются ли чем
VK> int *p;
VK> от
VK> int* p;

Hичем.

Best regards, Андрей

Alex Mogilnikov

unread,
Nov 28, 2007, 7:18:52 PM11/28/07
to
Привет Valera!

28 Nov 07 12:28, Valera Kolesnik писал Alex Mogilnikov:

AM>> Прочитать, наконец, правила языка. В том же п. 6.5.2.5 двумя

AM>> абзацами ниже приведенного мной отрывка описано, когда какой
AM>> storage class имеет объект, создаваемый compound literal (извини,
AM>> не знаю, как это правильно назвать по-русски).
VK> где их брать, эти правила?

Поищи в гугле документ iso9899, например вот это, наверное, он:
http://www.nirvani.net/docs/ansi_c.pdf и в нем ищешь пункт "Compound literals".

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

Указатели тут ни при чем, ты наступил на свосем другие грабли. Как я понял,
ты создаешь автоматический объект (вложенный литерал) и пытаешься использовать
его при инициализации статического объекта, о чем тебе компилятор и сообщает.
То есть ты делаешь примерно вот что:

void foo(void)
{
int a = 0;
static int b = a;
....

Valera Kolesnik

unread,
Nov 28, 2007, 12:27:10 PM11/28/07
to
Hello Andrey.

28 Nov 07 22:41, you wrote to me:

VK>> читаю Керниган, Ричи.

AT> Т.е. речь идет о С, а не о С++. Тогда не рекомендую запутывать народ,
AT> употребляя термин "ссылка" в вопросе о С, заданном в С++ конфе.
упс... эхой промахнулся. действительно, надо убегать отседова...

VK>> возник вопрос:
VK>> можно проинициализировать
VK>> static char *name[] = {"jan", "feb"};

VK>> как также проинициализировать
VK>> static int *v[]?

AT> В "традиционном" C (ANSI C89/90) - никак, так как "массивные" литералы в
AT> нем
AT> есть только для строк (как в примере выше). Для массивов 'int' литералов
AT> нет.
интересно, в каком году керниган и ричи свою книжку-то написали с таким
заданием. однако, весёлые ребята

AT> В "новом" же ANSI С99 есть литералы для любых массивов, поэтому там это
AT> можно
AT> сделать так

AT> static int *v[] = {
AT> (int[]) { 1, 2, 3 },
AT> (int[]) { 7 },
AT> (int[]) { 5, 5 }
AT> };
mingw ругается на такое. я уже здесь отписывал. если убрать static - не
ругается. с ним - очень.

VK>> и ещё. отличаются ли чем
VK>> int *p;
VK>> от
VK>> int* p;

AT> Hичем.
спасибо за ответ. кое-что новое я для себя почерпнул

Valera

Valera Kolesnik

unread,
Nov 28, 2007, 12:43:18 PM11/28/07
to
Hello Alex.

29 Nov 07 03:18, you wrote to me:

AM>>> Прочитать, наконец, правила языка. В том же п. 6.5.2.5 двумя
AM>>> абзацами ниже приведенного мной отрывка описано, когда какой
AM>>> storage class имеет объект, создаваемый compound literal (извини,
AM>>> не знаю, как это правильно назвать по-русски).
VK>> где их брать, эти правила?

AM> Поищи в гугле документ iso9899, например вот это, наверное, он:
AM> http://www.nirvani.net/docs/ansi_c.pdf и в нем ищешь пункт "Compound
AM> literals".
спасибо! за указание, что искать и даже где оно лежит - отдельное спасибо.
прочитал, сложил ответы остальных - проблема решилась.

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

AM> Указатели тут ни при чем, ты наступил на свосем другие грабли. Как я
AM> понял, ты создаешь
AM> автоматический объект (вложенный литерал) и пытаешься использовать его при
AM> инициализации
AM> статического объекта, о чем тебе компилятор и сообщает. То есть ты делаешь
AM> примерно вот что:

AM> void foo(void)
AM> {
AM> int a = 0;
AM> static int b = a;
AM> ....
AM> }
примерно да. просто в задании требуемый массив был внешним. я же все советы
проверял на массиве в main(). прочитав указанный пункт в скачанной книжке
понял, где собака зарыта.
всем поучавствовавшим в моём образовании спасибо. до изучения c++ больше нудеть
здесь не буду.

Valera

Andrey Tarasevich

unread,
Nov 29, 2007, 1:29:15 PM11/29/07
to
Wed Nov 28 2007 20:27, Valera Kolesnik wrote to Andrey Tarasevich:

AT>> В "новом" же ANSI С99 есть литералы для любых массивов, поэтому там это

AT>> можно сделать так

AT>> static int *v[] = {
AT>> (int[]) { 1, 2, 3 },
AT>> (int[]) { 7 },
AT>> (int[]) { 5, 5 }
AT>> };

VK> mingw ругается на такое. я уже здесь отписывал. если убрать static - не
VK> ругается. с ним - очень.

Если следовать букве стандарта, то такое определение, будучи расположенным
внутри тела функции, действительно является некорректным. Compound literal-ы,
так как они использованы внутри тела функции, будут иметь automatic storage
duration (по 6.5.2.5/6). Соответственно, указатели на них не будут адресными
константами (по 6.6/9) и не могу быть использованы для инициализации объекта
со static storage duration (по 6.7.8/4).

Если же расположить такое определение вне тела функции, то все в порядке, ибо
все compound literal-ы получат static storage duration.

Я с ходу не заметил, внутри функции ли ты это пытаешься делать или снаружи.

P.S. Вижу, что тебе уже про это написали...
P.P.S. Что интересно, Comeau Online в режиме С99 допускает подобное даже
внутри тела функции.

Best regards, Андрей

0 new messages