LINUX.ORG.RU

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

 , , openrange


1

3

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

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

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

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

Прошу прощения. Тупость сказал. Видать позднее время сказывается. первое слово a — это имя массива. Вопрос снимается

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

но в том и прикол что побитово для массивов

&a == a

Я не говорил о том, что &a==a, я говорил о том, что &a для массива имеет смысл.

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

если бы для всех литералов выолнялось бы это

Имя массива — не литерал.

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

то &4 обязанно было бы быть равно 4

Я же писал, что литерал не объект.

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

на 32х битах … ВСЕ массивы должны быть не больше 2Гб

Почему?

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

(bitvalue)a == (bitvalue)&a - что тут не ясного

а всё потому что для людей привычней одинаково записывать r-value и l-value

rvalue/lvalue не важно. Именно в этом примере всё как раз нормально, ИМХО, ибо преобразование массива в какое-то value определено. Как и взятие адреса массива. Очевидно, что результат одинаковый.

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

ибо есть a и есть &a[0]

ну и есть &a, которое равно &a[0]. Короткая запись. Как f(), где f это указатель на функцию.

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

Без этой фичи, и с возможности передать ссылку на массив, была-бы неоднозначность(неясно что передать, ссылку на массив, или указатель на первый эл-т)

Пример, пожалуйста.

не реализовано. Нет возможности передать массив в функцию.

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

Ну если-бы у тебя был массив находящийся по адресу 4, то для компилятора такой a был-бы равен 4. А например вместо a + 42 компилятор подставил-бы 46. Ещё было-бы верно, что такое a==4. И верно, что &a==4.

Для компилятора, кроме имени и значения, для переменной есть ещё и тип, а для массива — размер.

Ещё есть требования к памяти. Некоторые переменные требуют памяти для хранения своего значения, а некоторые переменные — не требуют, ибо сами являются значением. Ну а ещё есть некоторые, которые хоть и являются значением, но таки требуют места для этого значения, ибо у тебя есть нужда брать их адрес. Однако, с числовыми константами и с массивами эта фича не работает. Если попытаться взять адрес 4, компилятор сообщит об ошибке, а если попытаться получить адрес массива, компилятор вместо этого выдаст адрес первого эл-та.

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

пусть malloc выделяет, и проверяй на NULL

вот такая программа

#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <stddef.h>
int main()
{
        size_t len = (size_t)PTRDIFF_MAX + 2;
        char *p = malloc(len);
        printf("PTRDIFF_MAX=%ti\n", PTRDIFF_MAX);
        printf("len=%zu\np=%p\t%p\n", len, p, p+(len-1));
        p[len-1]=~*p;
        if (p[len-1] | *p == -1UL) puts("Ok"); else puts("Fail");
        return 0;
}
после компиляции
gcc -m32 test.c
выдает
PTRDIFF_MAX=2147483647
len=2147483649
p=0x77627008    0xf7627008
Ok

Т.е. malloc позволяет получить память размер которой не помещается в ptrdiff_t. И с этим участком памяти можно работать.

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

P.S.

$ uname -m ; free -g | head -n 2
x86_64
             total       used       free     shared    buffers     cached
Mem:             7          2          4          0          0          1

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

Так где твоя неоднозначность?

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

Для компилятора, кроме имени и значения, для переменной есть ещё и тип, а для массива — размер.

Размер массива — часть его типа.

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

&a тоже не имеет смысла

&a имеет смысл. Тип &a — указатель на массив. При разыменовании этого указателя получается массив исходного типа (в т.ч. того же размера).

#include <stdio.h>
int main()
{
        int (*p)[10], a[10];
        p = &a;
        printf("%d\n", sizeof(*p)/sizeof(**p));
        return 0;
}

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

Ты говорил, что без этой «фичи» (я правильно понимаю, что имеется в виду допустимость &a ?) была бы неоднозначность. Но теперь тебе кроме отсутствия «фичи» мешает еще и невозможность передать в функцию массив. Я все правильно понял?

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

Где мной было сказано, что определенность выражения &a — баг?

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

Массив где-то хранится, соответственно оператор & для него должен быть определен. Тип значения возращаемого оператором & для массива — указатель на массив. Таким образом определенность &a выводится из понятий массива и оператора &. Т.е. говорить о &a как о чем-то искусственно привнесенном нельзя. А о применении смотри мой пост

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

Возникает вопрос: влияет ли оптимизация на семантику языка?

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

если попытаться получить адрес массива, компилятор вместо этого выдаст адрес первого эл-та

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

4 — не объект, а литерал.

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

А, так ты про топик? Здесь про тот пост почти не говорят. Да и как-то странно сейчас выглядит слово «опять» в топике почти месячной давности.

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

Да. Пришел в сознание, огляделся. Странно это все.

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

если попытаться получить адрес массива, компилятор вместо этого выдаст адрес первого эл-та

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

вообще-то «адрес эл-та» и «указатель на» это совсем разные вещи, и не должны быть эквивалентными. Например «указатель на функцию», это такая переменная, в которой лежит адрес какой-то функции, указанного типа. Т.е. в машкоде это адрес указателя, указывающего на адрес функции. «Указатель на массив» это также переменная, в которой лежит адрес какого-то массива, т.е. первого эл-та.

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

это так, но вот указателем это не является.

4 — не объект, а литерал.

о чём и речь. array эквивалентен литералу «4» на уровне машинного кода, т.е. это тоже какая-то константа, ничем не лучше и не хуже четвёрки. Если я пишу 4+7, компилятор подставит в код 11, а если array лежит по адресу 0x400570, то вместо array+7 компилятор подставит 0x400577(тип char). Если я пишу array[7], то компилятор берёт память [0x400577].

Сравни это с переменной x, лежащей по адресу 0x400570. Если мне нужно это x, то компилятор берёт [0x400570], а если &x, то для компилятора это литерал 0x400570. Для array это правило работать не может, ибо нельзя взять адрес литерала. В коде его просто не может вообще быть, а даже если и есть, то он именно в коде, а не в данных.

drBatty ★★
()
Ответ на: здраствуй семён. от qulinxao

массив байт начинающийся в начале адресов может обращатся к последнему адресу mem[intMax] через a[intMax] только нарушая границу a

Че? Последний адрес - это intMax-1, т.к. мы идем с нуля.

Стоит тред читать, не? Скажите кто-нибудь.

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

Стоит тред читать, не?

Только если тебе интересны наркоманы.

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

Стоит, веселье начинается с определением ptrdiff_t.

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

Последнай адрес intMax-1. И это же значение — размер массива. Следовательно последний байт массива char находится по адресу intMax-2.

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

И если кому-нибудь кажется, что в

p=&a
есть неявное приведение типа, то эту строку можно спокойно убрать.

#include <stdio.h>

int main()
{
        int a[10];
        printf("%lu\n", sizeof(*&a)/sizeof(**&a));
        return 0;
}

Результат не поменяется.

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

array эквивалентен литералу «4» на уровне машинного кода

Мы же не про машинный код говорим, а про язык C. Так какая разница что чему там эквивалентно на уровне машинного кода?

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

указателем это не является.

Что указателем не является? Адрес массива? Почему? Потому что нет указателей на массив? А какой там тип у p?

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

Мы же не про машинный код говорим, а про язык C. Так какая разница что чему там эквивалентно на уровне машинного кода?

тогда воспринимай как данность, что

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

Что указателем не является? Адрес массива? Почему? Потому что нет указателей на массив? А какой там тип у p?

&a для массива a является не указателем на массив, а указателем на первый эл-т массива. На самом деле «указатель на массив» это несколько другая ерунда, и она НЕ реализована в C. Если-бы была реализована, то размер разименованного указателя на массив был-бы равен размеру массива. Но разименованный «указатель на массив» имеет размер первого эл-та, потому тип этого твоего p получается «указатель на эл-т».

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

Конечно данность — в стандарте определено, что a почти во всех выражениях преобразуется в указатель на первый элемент.

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

&a для массива a является не указателем на массив, а указателем на первый эл-т массива

Их значения (битовые представления) совпадают но типы разные.

&a для массива a является не указателем на массив

Ты код, который я привожу вообще смотришь?

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

На самом деле «указатель на массив» это несколько другая ерунда, и она НЕ реализована в C

А здесь я что объявляю

int (*p)[10];

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

Если-бы была реализована, то размер разименованного указателя на массив был-бы равен размеру массива. Но разименованный «указатель на массив» имеет размер первого эл-та, потому тип этого твоего p получается «указатель на эл-т».

Ну ты и фантазер.

#include <stdio.h>
int main()
{
    int (*p)[10];
    printf("%zu\t%zu\n", sizeof(*p), sizeof(int));
    return 0;
}
Результат выполнения

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

Это по поводу возможности сравнения. По поводу равенства адресов я уже писал, что адрес первого элемента совпадает с адресом массива.

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