LINUX.ORG.RU

Дурацкий вопрос по С


0

0

Привет. Меня жестко климануло и я задался вопросом, просматривая код одной шняги на С без крестов:

....
//Global static
int pthread_id;
char env_forked[][];
....
Дальше пошли функции.

Что В ТОЧНОСТИ означает char env_forked[][];

1. Попытка определить указатель на строковый массив (память не выделена при компиляции)
2. Попытка определить что-то типа динамического массива, т.е. далее в функциях можно присвоить любые значения типа snprintf(env_forked[0],n,"aaa"); snprintf(env_forked[1],n,"ббб"); snprintf(env_forked[2],n,"ввв"); и т.д. сколько заблагорассудится (по-моему такое что-то в этом роде было на очень старых компилерах и машинах лет 30 назад).
3. Аффтар кода мудак и так вообще не пишут.

★★

это вообще не должно компилироваться. во всяком случае у меня 

static char test[][];

int main(int argc, char *argv[])
{
  return 0;
}

gcc не компилируется.

alex4
()
Ответ на: комментарий от alex4

а, static там не было. ну и без static не компилируется.
может этот кусок кода просто отключен с помощью препроцессора?

alex4
()
Ответ на: комментарий от ratatosk

Компилить не пытался, код старого проекта. Как адресовать? Также как и ** Насколько я понимаю.

На extern - не похоже, т.к. собсно слова extern нет. :)

Ну вобщем это лажа. Такого по идее не бывает. Спасибо за поддержку

З.Ы Вот хоть лишите меня клавы - но кажется мне, что писали так лет пятнадцать назад. Подозреваю, что такой диалект был. для интереса возьму вот DECUS C и прогоню в эмуляторе RT-11 чё он скажет ;)

Alphaer ★★
() автор топика

> Что В ТОЧНОСТИ означает char env_forked[][];

Примерно то же, что и char **env_forked;.

Deleted
()
Ответ на: комментарий от Deleted

> > Что В ТОЧНОСТИ означает char env_forked[][];

> Примерно то же, что и char **env_forked;.

Это разве что в каком нибудь кривом диалекте. Ты sizeof попробуй для них сделать.

ubber
()

char a[M][N]; // массив из M массивов по N байт
&a[i][j] == a + i * N + j; // M тут не нужно, поэтому можно и так:
char b[][N]; // массив неизвестной длины из массивов по N байт
&b[i][j] == b + i * N + j;
char c[][]; // вообще размеры не известны...
&b[1][0] == ???
char *p; // указатель на массив байт
&p[i] = p + i;
char **q; // указатель на массив из указателей на массивы байт
&q[i][j] = *(q + i) + j;

Итого: char[M][N] и char** имеют разную внутреннюю структуру,
а как работать с char[][] - вообще непонятно.

const86 ★★★★★
()

Компилиться не должно. И это СОВСЕМ не то же самое, что char **env_forked.

В общем, 3.

svu ★★★★★
()
Ответ на: комментарий от ubber

>> Примерно то же, что и char **env_forked;.

> Это разве что в каком нибудь кривом диалекте. Ты sizeof попробуй для них сделать.


Да, это я ступил. Извиняюсь за дезинформацию.

P.S. Пятница, вечер...

Deleted
()
Ответ на: комментарий от const86

>--char a[M][N]; // массив из M массивов по N байт >--&a[i][j] == a + i * N + j; // M тут не нужно, поэтому можно и так О мой Керниган и Риччи. Какой кошмар, двойка, и на пересдачу не приходите. Имя двумерного массива - это есть указатель на массив из указателей на одномерные массивы(байты, как хотите). Как можно его(указатель на массив из указателей) приравнивать к адресу элемента массива символов??? Ужас. GCC на это говорит lvalue required as left operand of assignment. Правильно : &a[i][j] == *(*a+i)+j или тогда уж char *a_ptr = &a[0][0]; и потом &a[i][j] == a_ptr + i*N + j;

>--// M тут не нужно, поэтому можно и так:char b[][N]; // массив неизвестной длины из массивов по N байт Вы это пробовали скомпилить ? Офигеть просто... Не учите других всякой фигне. Конечно нахрен оно нужно, си у нас же автоматически проверяет выход за границы массива. 2-ка. Учи матчасть.

gcc
()
Ответ на: комментарий от gcc

> Имя двумерного массива - это есть указатель на массив из указателей на одномерные массивы(байты, как хотите).

huh? все он правильно написал.

dilmah ★★★★★
()
Ответ на: комментарий от dilmah

>huh? все он правильно написал.

Хто ?

Попробуйте этот код осмыслить, а потом скомпилить если первое не удалось.

>char a[M][N]; // массив из M массивов по N байт >&a[i][j] == a + i * N + j; // M тут не нужно, поэтому можно и так:

В данном случае а есть то же самое что и char **a или char (*a)[5]. Нельзя к этому а прибавить какое-то число и всё, ПРОСТО НЕЛЬЗЯ, не будет это адресом элемента в двумерном массиве. Сам немного ошибся в пред посте, правильно будет так: char a[N][M]; &a[i][j] == *a + i*M + j; а предыдущее &a[i][j] == *(*a+i)+j; будет верно если убрать амперсанду в левой части выражения или добавить в начало за скобки к правой

gcc
()
Ответ на: комментарий от dilmah

Вот, пожалуйста, на примере, закоменьте строки 79-82, после попыток скомпилить. После того как закоментируете, скомпильте код(компилится c --pedantic --Wall -Wextra(argc,argv только подрихтовать)) и потом подумайте, поймите наконец как массивы в си огранизованы.

http://pastebin.com/m6069b1f6

gcc
()
Ответ на: комментарий от ubber

> Это разве что в каком нибудь кривом диалекте

ога

int main(int argc, char **argv)

ip1981 ☆☆
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.