читаю Керниган, Ричи. возник вопрос:
можно проинициализировать
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
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}};
уже не работает?
сорри я не слежу за С, давно не нужен был
... Либерализм - затыкание ртов под вопли о свободе слова.
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
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]
Алексей М.
... Старый глюк лучше новых двух...
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
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]
Алексей М.
... Слепой Пью, Глухой Ем...
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
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, Андрей
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;
....
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
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
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, Андрей