LINUX.ORG.RU

максимальное число элементов в массиве в С?

 , , openrange


1

3

эт что же массив(еденичных элементов) по определению меньше всего адресного пространства ??

т.е если вся память адреса 0...2^64-1 то массив элементов единичного размера начинающийся с 0 адресса не может в себе содержать элемент максимального значения типа индекса

( ща когда 64 бита это не очень актуально но для 32 и тем более 16 оказывается массив(байтов) обязан быть меньше сегмента байтов.)

★★☆
Ответ на: комментарий от anonymous

разве это было при обсуждении лавсана, vsl, лиспа и лисперов? superhackkiller1997 в том обсуждении не участвовал, а сообщение явно в его духе.

я по ссылке ходил. Оттуда и цитировал.

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

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

ИМХО просто недопилили передачу массива, а потом было уже поздно. Хотя и есть бесполезная форма для передачи массива int foo(int a[]), которая не работает как надо.

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

Я спрашивал про обощенную коллекцию, а не про ее индекс

а я говорил как раз про индекс, и его отличие от размера.

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

отличие в том, что в моей коллекции может быть и массив, и список, и ассоциативный массив.

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

С чего вдруг? Тебя же никто не заставляет считать разность между суммой и каким-либо ее слогаемым.

определение разности может служить и определением суммы, ибо это взаимно-однозначные обратные операции (если не выходить за ОДЗ, которое чётко определено).

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

нет ибо If the result is not representable in an object of that type, the behavior is undefined

что «нет»?

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

(если не выходить за ОДЗ, которое чётко определено)

Ты не понимаешь силы этого высказывания. Оно полностью делает твои рассуждения не применимыми т.к. мы и обсуждаем выход из ОДЗ для одной из операций. К тому же, в стандарте сказано, что вычисленная разность приводиться к типу ptrdiff_t, а про аргумент прибавляемый к указателю такого не говорится.

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

Что еще за адрес адреса? Где храниться тот адрес, адрес которого ты упоминаешь?

где-то в памяти компилятора во время компиляции. В интерпретаторах любая переменная это указатель, в компиляторах переменная заменяется на конкретный адрес(т.е. константный указатель). Т.е. если в коде C написано int x = 0x123, то компилятор пишет MOV [0x1234567], 0x123. Вот только const в сишечке тогда не было, вот и получилось, что указатель стал неконстантным. Ну и потребовал для своего изменения ещё памяти, в силу того, что указатели можно двигать. А константные указатели до сих пор не требуют памяти для своего хранения(в рантайме), т.е. эквивалентны массивам и простым скалярным переменным.

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

И какой общий интерфейс ты у них видишь? Напоминаю, что из существования множества всех множеств получается парадокс Кантора — не следует злоупотреблять обобщением.

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

всё таки для массивов &m==m есть фича

это не фича, а бессмыслица.

как следствие несколько мозголомное &m== m ибо по сути константа(смещение для локального случая) не имеет отдельного места хранения при исполнении

да нет тут ничего «мозголомного», к в любой бессмыслице.

Да, константа не требует места для хранения своего значения в памяти данных. Ибо хранится в коде. Явно или неявно. Из этого факта никак НЕ следует, что m равно своему адресу.

Указатель требует память на хранение адреса лишь потому, что может изменяться в рантайме. Потому приходится хранить адрес указателя, и ещё сам указатель. Для массива, константного указателя, и простой переменной явно хранить значение адреса не нужно, просто потому, что он никогда не меняется. А НЕ потому, что это одно и то же.

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

Ты не понимаешь силы этого высказывания. Оно полностью делает твои рассуждения не применимыми т.к. мы и обсуждаем выход из ОДЗ для одной из операций.

что тут обсуждать. если это UB?

К тому же, в стандарте сказано, что вычисленная разность приводиться к типу ptrdiff_t, а про аргумент прибавляемый к указателю такого не говорится.

вот и я не нашёл.

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

эта бесмыслица ( мозголомство именно от того что прибито гвоздями) захардкожена в с

нет тут следствия .

тут определние языка lkz vfccbdf &m == m

qulinxao ★★☆
() автор топика
Ответ на: комментарий от anonymous

И какой общий интерфейс ты у них видишь? Напоминаю, что из существования множества всех множеств получается парадокс Кантора — не следует злоупотреблять обобщением.

никакого общего интерфейса я не вижу, про Кантора знаю, но это никак не мешает мне утверждать, что индекс к размеру отношения НЕ имеет.

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

m равно своему адресу

Напоминаю, что в почти всех выражениях языка C имя массива преобразуется к указателю на первый (со смещением 0) элемент.

char m[1000];
sizeof(m); // == 1000
sizeof((1,m)); // == sizeof(char *)

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

Индекс чего? К размеру чего? Ты же сам писал, что в C для массивов максимальный индекс равен количество элементов минус 1.

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

эта бесмыслица ( мозголомство именно от того что прибито гвоздями) захардкожена в с

наверное ты просто этого не понимаешь. Мне это видится простым и логичным.

&m == m

а это — бред.

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

а кто и где говорит о об одном и томже

из тождественности не следует одинаковость

вот такой кривой С - переносимый ассемблер

qulinxao ★★☆
() автор топика
Ответ на: комментарий от drBatty

до введения void -это было идеальное истиное тождество.

сечас при вызове функции компилятор молчА сьест взятие адресса при передаче массива (если ты по простоте душевной возмёш )

qulinxao ★★☆
() автор топика
Ответ на: комментарий от drBatty

ты умеешь ориентироваться в дереве комментариев? не все сообщения после указанного относяться к нему.

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

Напоминаю, что в почти всех выражениях языка C имя массива преобразуется к указателю на первый (со смещением 0) элемент.

int x = 5;

ВНЕЗАПНО константа 5 превращается в значение 5+0. Тебя это не удивляет? А почему удивляет, что адрес массива 0x12345 преобразуется в указатель 0x12345?

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

Для массива, константного указателя, и простой переменной явно хранить значение адреса не нужно, просто потому, что он никогда не меняется

Объясника вывод программы

#include <stdio.h>
int main()
{
        char m[1000];
        const char c='x';
        const char *cp=&c;
        const char const *ccp=&c;
        const char * const cpc=&c;
        printf("m=%p\n&m=%p\n&c=%p\n&cp=%p\n&ccp=%p\n&cpc=%p\n",m,&m,&c,&cp,&ccp,&cpc);
        return 0;
}

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

А НЕ потому, что это одно и то же.

Опять ты говоришь сам с собой.

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

что тут обсуждать. если это UB?

Вычисление разности между указателями, если значение этой разности не помещается в ptrdiff_t — UB, вычисление суммы указателя и числа не помещающегося в ptrdiff_t — в стандарте не сказано, что это UB. Сложение и вычитание это разные операции, хотя и имеющие связь при некоторых значенях аргументов. Сложение и вычитание имеют разные ОДЗ

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

никакого общего интерфейса я не вижу, про Кантора знаю

И это тебе не мешает говорить про обобщенную коллекцию?

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

&a

а что ты хотел? Адрес массива? Получи. Значение указателя? Пожалуйста. И они да, равны. Вот только второе 'a' это УЖЕ указатель, а первое 'a' это ЕЩЁ массив. Потому-то они и равны, ибо для преобразования в (long long) массив необходимо переделать в указатель(ибо вообще говоря массив в скаляр преобразовать в принципе невозможно, а вот через указатель — без проблем).

Ты доказал лишь то, что массив в сишечке умеет неявно превращаться в указатель.

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

массива 0x12345

Что такое массив 0x12345? Если массив начинающийся с адреса 0x12345, то об этом я тебе и напоминал. Т.е. выражение &m==m не означает что массив и указатель на массив одно и то же. Но ты в своих рассуждениях почему-то исходишь именно из этого.

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

Индекс чего? К размеру чего? Ты же сам писал, что в C для массивов максимальный индекс равен количество элементов минус 1.

не просто «равен», а только «численно равен». На самом деле это разные вещи, и индекс равен только численно, и то лишь по счастливому совпадению, связанному с удачным выбором базы, и ограниченной ОДЗ индекса. Взяв другую базу, и/или выйдя за ОДЗ ты всё поломаешь.

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

В интерпретаторах любая переменная это указатель

Какие-то у тебя странные фантазии. Переменная — она и в интерпритаторе переменная. И интерпритатор и компилятор каким-то образом хранят соответствие имени переменной участку памяти в котором храниться ее значение. В компиляторах структура, где хранится такое соответствие, называется таблицей символов.

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

Мне все строки понятны. Мне не понятно как они согласуются с

А константные указатели до сих пор не требуют памяти для своего хранения(в рантайме)

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

вычисление суммы указателя и числа не помещающегося в ptrdiff_t — в стандарте не сказано, что это UB

сказано. Ибо если не лезет в ptrdiff_t, то значит заведомо за границей массива. И сл-но UB.

Сложение и вычитание это разные операции, хотя и имеющие связь при некоторых значенях аргументов. Сложение и вычитание имеют разные ОДЗ

ОДЗ ограничена намного сильнее, т.к. если в массиве 0x12345 два эл-та, то ОДЗ результата 0x12345,0x12346, и 0x12347. И ВСЁ. Т.е. при начальной базе ОДЗ индекса 0 и 1 и 2. Причём последнее значение нельзя разименовывать. ЕМНИП это «замкнутость» называется вроде. На массив из двух эл-тов мы имеем 3 допустимых адреса и три допустимых индекса. При этом сложение и вычитание вполне определены и однозначны. И массив заведомо влезает в ptrdiff_t (его размер), ибо ptrdiff_t заведомо умещает в себя разность любых двух указателей, в частности указателя на первый, и на фиктивный на 1 за последним эл-ты. А следовательно размер массива (любого) туда тоже влезет. А следовательно и размер суммы от начала и до конца.

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

И это тебе не мешает говорить про обобщенную коллекцию?

про её индекс, точнее про то, что индекс к размеру не относится — не мешает.

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

Тебя удивляет что массив равен своему адресу.

меня бред не удивляет. А раздражает.

В данном случае содержимое указателя, в который преобразован массив, равно адресу этого массива. Это меня НЕ удивляет. А почему должно?

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

То у тебя

что индекс к размеру отношения НЕ имеет

То у тебя максимальный индекс «численно равен» количество элементов минус 1 при определенных значениях значениях базы и количества элементов. Ты уж определись.

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

Т.е. выражение &m==m не означает что массив и указатель на массив одно и то же. Но ты в своих рассуждениях почему-то исходишь именно из этого.

Во первых «указатель на массив 0x12345» это такая переменная, в которой лежит 0x12345. А массив — область памяти начиная с 0x12345. Это конечно разные вещи. С другой стороны, ты сравниваешь «указатель на массив равный 0x12345» с «указателем на массив, который автоматически получен из массива 0x12345», и получаешь, что они оба 0x12345. Что тут удивительного?

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

Взяв другую базу

А нельзя в C взять другую базу. Твое a[-1] по стандарту UB

If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined.

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

выйдя за ОДЗ

Если количество элементов положительно помезается в ОДЗ типа, то и (количество элементов-1) тоже будет помещаться в этот тип.

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

В интерпретаторах любая переменная это указатель

Какие-то у тебя странные фантазии. Переменная — она и в интерпритаторе переменная. И интерпритатор и компилятор каким-то образом хранят соответствие имени переменной участку памяти в котором храниться ее значение. В компиляторах структура, где хранится такое соответствие, называется таблицей символов.

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

Вот только массив, в отличие от скаляра, имеет кроме константы, ещё и размер.

В сишечке массив с лёгкостью отбрасывает свой размер, и становится скаляром, а именно константным указателем. Точно также тип char сам по себе превращается в int, если его например сравнить с другим int'ом. Потому char можно сравнить с int, а массив можно сравнить с указателем.

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

то значит заведомо за границей массива

Почему? Откуда это следует? Нигде не сказано, что количество элементов в массиве должно помещаться в ptrdiff_t. Более того размер массива в байтах (sizeof(char [10])) должен помещаться в size_t, который беззнаковый тип.

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

Мне все строки понятны. Мне не понятно как они согласуются с

А константные указатели до сих пор не требуют памяти для своего хранения

что тут непонятного? Для обычного указателя int* тебе нужно хранить 8 байт, в котором этот int* лежит. И ещё 8 байт с адресом тех 8 байт(внутри команды например, или в регистре, который на стек указывает, или ещё где-то). Для константного указателя на int* достаточно хранить только 8 байт, которые указывают на этот(эти) 4х байтные int. Эти 8 байт могут быть явно записаны прямо в команде, как и любая константа, известная при компиляции.

Хорошо, какая строка не согласуется?

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

ЕМНИП это «замкнутость» называется вроде

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

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

При этом сложение и вычитание вполне определены и однозначны

При каких значениях аргументов?

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

То у тебя максимальный индекс «численно равен» количество элементов минус 1 при определенных значениях значениях базы и количества элементов. Ты уж определись.

в сишечке в силу некоторых совпадений обычно индекс имеет какое-то отношение к размеру. Например размер ОДЗ индекса равен размеру массива. При некоторых условиях максимальный индекс действительно численно равен размеру массива, даже без -1.

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

ибо ptrdiff_t заведомо умещает в себя разность любых двух указателей

Почему ты так решил?

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

Значит про обобщенную коллекцию ты не говоришь, но про индекс ее говоришь. Как мы можем рассматривать аттрибут того чего, возможно, нет?

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

Я посмотрю, возникает разночтение, где я говорю указатель и имею в виду его значение, а где говорю указатель и имею в виду переменную такого типа. Хорошо, в дальнейшем для первого случая буду использовать «адрес».

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