LINUX.ORG.RU

a[b] и b[a] - одно и то же???


0

0

#include <stdio.h>
char a[] = "CHUDO";
int main() { printf("%c %c %c %c %c\n",0[a],1[a],2[a],3[a],4[a]); }

Скомпильте... результат, как говориться, налицо.... есть какие-нибудь варианты почему оно так???
anonymous

Ага, а ещё можно так:

*(a+0), *(a+1) ....

а что, тебя не учили этому? Ай-яй-яй... учить матчасть до просветления что же такое массивы, и как они устроены ;)

Cy6erBr4in ★★★
()

По стандарту 3[a] и т.п. писать нельзя. Это undefined behavior, потому что операции адресной арифметики определены только в пределах границ одного массива + 1 элемент.

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

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

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

А в разных сегментах кода - своя система команд. Ужоснах...

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

Нельзя _в общем случае_. Undefined behavior => компилятор волен сделать программу, которая работает сообразно логике, а может и неработающую/падающую в корку выдать.

Я не знаю системы, на которой бы не работали конструкции типа *(3 + a), но по логике очевидно, что такие есть (какие-нибудь специфические микроконтроллеры, или просто очень древние компьютеры).

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

Что-то я не слышал про компьютеры с нелинейным адресным пространством... Про paged memory слышал и даже работал, но адресуемая память всегда линейной была. Кто-нибудь знает про такое железо?

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

Нет, они просто видимо тоже не знают примеров таких компьютеров %))

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

Да, уже и забывать начинаю, что Си - это продвинутый макроассемблер :)

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

> Я не знаю системы, на которой бы не работали конструкции типа *(3 + a), но по логике очевидно, что такие есть

Нет(С)

Сложение коммутативно. В адресной арифметике нигде сказано что именно левый операнд должен быть указателем:

For addition, either both operands shall have arithmetic type, or one operand shall be a pointer to an object type and the other shall have integer type.

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

мда, всё так. Ограниченияна адресную арифметику тут вообще ни при чём. В стандарте оператор [] буквально определён так, что a[b] эквивалентно *((a) + (b)), что что это реально одно и то же.

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

Вот если бы ты написал *( (char*)3 + (int)a ) это была бы проблема, хотя и работало бы наверняка почти везде.

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

наш вагон какашек стоит на запасном пути

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

>это лишний раз доказывает, что в Ц массивов как типа нет.

andrey@silverblood (~)$ cat dummy1.c       
int main()
{
 char a[4];
 a++;
 return 0;
}
andrey@silverblood (~)$ cat dummy2.c 
int main()
{
 char a[4];
 char *b = a;
 b++;
 return 0;
}
andrey@silverblood (~)$ gcc dummy1.c                                                                          
dummy1.c: In function 'main':
dummy1.c:4: error: lvalue required as increment operand
andrey@silverblood (~)$ gcc dummy2.c 
andrey@silverblood (~)$ 

ась?

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

Нет я конечно понимаю что тут явно этого нет, но возможно реализовано это примерно так же :)

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

http://www.opennet.ru/docs/RUS/ansi-c/ansi-c-5.html

Объявленный как массив идентификатор представляет указатель, значение которого есть адрес первого элемента массива. Пойнтер указывает на тип элементов массива. Если series объявлен как массив 10 целых элементов, то идентификатор series представляет адрес массива и выражение индекса series[5] ссылается на целое значение, которое есть шестой элемент series. [...] Адрес массива не меняется при выполнении программы, хотя значения отдельных элементов массива могут меняться. Значение указателя, представленное идентификатором массива, это не переменная, поэтому идентификатор массива не может стоять левым операндом в операции присвоения.

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