Массив с переменной длиной (объявленный глобальным и локальным. Чем обусловлена разница?)

Модератор: Модераторы разделов

promov
Сообщения: 384
Статус: Участник
ОС: Debian GNU/Linux

Массив с переменной длиной

Сообщение promov »

Проще говоря, эта программа работает

Код: Выделить всё

#include <stdio.h>
int main () {
 int j= 4;
 int h [j];
 return 0;
}


а эта нет

Код: Выделить всё

#include <stdio.h>
int j= 4;
int h [j];
int main () {
 return 0;
}


Комментировать не стал, всё ясно, как день, по моему. Во втором случае машина выдаёт информацию variably modified ‘h’ at file scope.
Всё же правильно вроде... Ну пусть во втором случае массив объявлен глобальным, ну и что?
Переменная j заранее ведь определена. И синтаксис соблюдён. И вот ещё: чем таким принципиальным отличается вторая программа от третьей?:

Код: Выделить всё

#include <stdio.h>
int h [4];
int main () {
 return 0;
}


Третья-то работает. В дебри, наверное, влазить надо... Надеюсь на помощь. C уважением promov.
Или так: в языке C существует правило- массив неопределённой длины не может быть глобальным. Если бы кто-нибудь указал мне на место где это правило* прописано я был бы ему очень благодарен.

*само собой это не разумеется.
Зачем хорёк пошел в ларёк, зачем барсук полез на сук...
Мораль легко уразуметь: зачем на бал пришёл медведь?
Спасибо сказали:
Аватара пользователя
Uncle_Theodore
Сообщения: 3339
ОС: Slackware 12.2, ArchLinux 64

Re: Массив с переменной длиной

Сообщение Uncle_Theodore »

Переменная, объявленная на уровне файла не может быть модифицирована по размеру.
Чиаийте тут, например, хотя в этих стандартах разобраться не так-то просто...
http://techpubs.sgi.com/library/tpl/cgi-bi..._html/ch04.html
Спасибо сказали:
Аватара пользователя
m11
Сообщения: 147
ОС: Gentoo Linux ~x86

Re: Массив с переменной длиной

Сообщение m11 »

promov писал(а):
11.10.2007 20:35
в языке C существует правило- массив неопределённой длины не может быть глобальным.

почему не может?
кто мешает объявить глобальную переменную указателем,
выделеть под нее память на несколько элементов,
и использовать ее как полноценный массив?
Let your mind be free
мой блог
Спасибо сказали:
Аватара пользователя
Uncle_Theodore
Сообщения: 3339
ОС: Slackware 12.2, ArchLinux 64

Re: Массив с переменной длиной

Сообщение Uncle_Theodore »

m11 писал(а):
11.10.2007 21:48
promov писал(а):
11.10.2007 20:35
в языке C существует правило- массив неопределённой длины не может быть глобальным.

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

Извините, коллега, но ссылка и массив -- это все-таки две большие разницы. Под массив Вы руками память не выделяете, а хотите, чтобы это сделала программа.
Спасибо сказали:
Аватара пользователя
m11
Сообщения: 147
ОС: Gentoo Linux ~x86

Re: Массив с переменной длиной

Сообщение m11 »

Uncle_Theodore писал(а):
11.10.2007 22:04
Извините, коллега, но ссылка и массив -- это все-таки две большие разницы. Под массив Вы руками память не выделяете, а хотите, чтобы это сделала программа.

Разница между тем, что я описал и объявлением массива с помощью [ ],
лишь в способе выделения памяти - динамический и статический соответственно (со всеми вытекающими последствиями).
А результат один и тот же - указатель на начало выделенного куска памяти заданной длины.
Let your mind be free
мой блог
Спасибо сказали:
Аватара пользователя
Uncle_Theodore
Сообщения: 3339
ОС: Slackware 12.2, ArchLinux 64

Re: Массив с переменной длиной

Сообщение Uncle_Theodore »

m11 писал(а):
11.10.2007 22:27
Uncle_Theodore писал(а):
11.10.2007 22:04
Извините, коллега, но ссылка и массив -- это все-таки две большие разницы. Под массив Вы руками память не выделяете, а хотите, чтобы это сделала программа.

Разница между тем, что я описал и объявлением массива с помощью [ ],
лишь в способе выделения памяти - динамический и статический соответственно (со всеми вытекающими последствиями).
А результат один и тот же - указатель на начало выделенного куска памяти заданной длины.

В случае указателя Вы выделяете память. А в случае [] -- выделяет память программа. Соответственно, компилятор устанавливает правила того, как можно объявлять массив, а как нет.
Давайте не будем таблицу умножения наизусть цитировать. Я знаю, как устроены массивы с Сях. И результат не совсем одно и то же...
Спасибо сказали:
Аватара пользователя
Liksys
Сообщения: 2910

Re: Массив с переменной длиной

Сообщение Liksys »

Внесу и свои пять копеек :)
То, что массивы и указатели - это разные вещи уже сказали, результат кстати получается разным, к именам массива арифметика указателей не применима в полном объеме.
Спасибо сказали:
promov
Сообщения: 384
Статус: Участник
ОС: Debian GNU/Linux

Re: Массив с переменной длиной

Сообщение promov »

Uncle_Theodore писал(а):
11.10.2007 21:31
Чиаийте тут, например, хотя в этих стандартах разобраться не так-то просто...
http://techpubs.sgi.com/library/tpl/cgi-bi..._html/ch04.html


Спасибо, конечно, но я лучше на веру приму, что
promov писал(а):
11.10.2007 20:35
в языке C существует правило- массив неопределённой длины не может быть глобальным.

Если это правда- хорошо. Если неправда- ну что ж, рано или поздно,( как прижмёт, что называется) придётся мне такое своё знание пересматривать. Пока оно работает, буду им руководствоваться и помнить, что правило выведено мной опытным путём и в любом случае может дать осечку.
Это альтернатива изучению английского языка.
Зачем хорёк пошел в ларёк, зачем барсук полез на сук...
Мораль легко уразуметь: зачем на бал пришёл медведь?
Спасибо сказали:
Аватара пользователя
m11
Сообщения: 147
ОС: Gentoo Linux ~x86

Re: Массив с переменной длиной

Сообщение m11 »

Спорить на эту тему по-моему бессмысленно, но лично я всегда рассматривал массив, заданный с помощью [ ], как частный случай указателя.
С упрощением в виде отсутствия необходимости вручную вызывать функцию выделения памяти, а также рядом наложенных ограничений таких как, например, фиксированный срок жизни, отсутсвие возможности вручную ее освободить, или ограничения, описанного в первом посте данной темы и многих других.

А под словом массив, насколько я знаю, принято иметь ввиду все же каким-либо образом проиндексированный набор подобных единиц информации, а не вот эту конструкцию с использованием [ ]. (хотя вопрос тоже спорный)
Let your mind be free
мой блог
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: Массив с переменной длиной

Сообщение v04bvs »

m11 писал(а):
11.10.2007 23:01
Спорить на эту тему по-моему бессмысленно, но лично я всегда рассматривал массив, заданный с помощью [ ], как частный случай указателя.
С упрощением в виде отсутствия необходимости вручную вызывать функцию выделения памяти, а также рядом наложенных ограничений таких как, например, фиксированный срок жизни, отсутсвие возможности вручную ее освободить, или ограничения, описанного в первом посте данной темы и многих других.

А под словом массив, насколько я знаю, принято иметь ввиду все же каким-либо образом проиндексированный набор подобных единиц информации, а не вот эту конструкцию с использованием [ ]. (хотя вопрос тоже спорный)


В С++ массив и указатель это разные типы, что проявляется, в частности, при перегрузке функций. К массиву можно применять sizeof и он вернёт размер массива.
Спасибо сказали:
sergio
Сообщения: 436
Статус: Интересующийся новичок
ОС: Debian GNU/Linux 4 & 5

Re: Массив с переменной длиной

Сообщение sergio »

Маленькое юридическое уточнение:
в языке C существует правило- массив неопределённой длины не может быть глобальным.

Дело не в глобальности, а в классе хранения. Массив неопределённой длины не может иметь статический класс хранения. Грубо говоря, при компиляции такой массив будет зашит в сегмент данных вашего выполняемого файла, в куче со всеми литералами и глобальными константами, есессно его размер на момент компиляции должен быть известен, иначе сколько зашивать-то? :)
Массивы с автоматическим хранением получаются сдвигом указателя стэка во время выполнения, там все просто (хотя десять лет назад и для них требовался константный на момент компиляции размер). Неглобальный но статический массив внутри функции GCC тоже не дает объявить зависимым от переменной.

Вернее, он будет зашит, если чем-то инициализирован. Если нет, то видимо GCC генерит для него разворачивание-размещение после загрузки (до входа в main и пр.). Но возможно это все детали реализации, надо стандарты смотреть. :)
Debian GNU/Linux 4 -- AMD Athlon64 3000+ / Asus 7600GS -- Gnome
Debian GNU/Linux 5 -- Dell (Vostro) 500 (Celeron M560 / iGM965) -- Gnome
Спасибо сказали:
promov
Сообщения: 384
Статус: Участник
ОС: Debian GNU/Linux

Re: Массив с переменной длиной

Сообщение promov »

Вот, кажется, ответ на мой вопрос:
"Внутри функции или блока можно задавать размер массива с помощью выражений, содержащих переменные. В этом случае размер массива вычисляется во время выполнения программы. Например, в функции

int makeValis (int n) {
int valArray [n];
...
}

объявляетсяавтоматически массив с именем valArray и размером n элементов, где значение n вычисляется во время выполнения и может изменяться при отдельных вызовах этой функции. Массивы переменного размера нельзя инициализировать во время объявления."
Cтефан Кочан, "Программирование на языке С", Москва- Санкт-Петербург- Киев, 2007 год.
Естественно, в конце книги, среди перечня чего-то там, мелкими буквами.

Я это пишу для таких же бедолаг, как я, благо название темы гвоворит само за себя и им легко (относительно) будет найти ответ на этот вопрос, если, конечно, второй возникнет.
Зачем хорёк пошел в ларёк, зачем барсук полез на сук...
Мораль легко уразуметь: зачем на бал пришёл медведь?
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: Массив с переменной длиной

Сообщение v04bvs »

На всякий случай напишу - массивы такого рода допустимы только в C, по стандарту С++ они не допустимы (хотя многие компиляторы поддерживают эту возможность в качестве расширений).
Спасибо сказали: