Форум программистов, компьютерный форум CyberForum.ru

Почему работает и так, и так: arr[i] и i[arr]? - C++

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 42, средняя оценка - 4.90
ForwardM
1 / 1 / 0
Регистрация: 14.05.2012
Сообщений: 5
14.05.2012, 21:20     Почему работает и так, и так: arr[i] и i[arr]? #1
C++
1
2
3
//один и тот же результат
cout<<arr[i];
cout<<i[arr];//почему нет ошибки
да даже это, например работает и выводит одинаковый результат
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// arrh.cpp: определяет точку входа для консольного приложения.
//
 
#include "stdafx.h"
#include <conio.h>
#include <iostream>
 
 
using namespace std;
 
 
int _tmain(int argc, _TCHAR* argv[])
{
    int *arr1 =new int[7]; 
    for (int i=1; i<=7;i++)
        arr1[i]=(i+1)*10;
    
        cout<<"arr1"<<"="<<arr1[2]<<endl;
        cout<<"arr1"<<"="<<2[arr1]<<endl;
    
    getch();
    return 0;
}
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ForwardM
1 / 1 / 0
Регистрация: 14.05.2012
Сообщений: 5
15.05.2012, 08:37  [ТС]     Почему работает и так, и так: arr[i] и i[arr]? #21
Всем большое спасибо.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16943 / 5348 / 329
Регистрация: 30.03.2009
Сообщений: 14,383
Записей в блоге: 26
15.05.2012, 08:49     Почему работает и так, и так: arr[i] и i[arr]? #22

Не по теме:

Цитата Сообщение от lazybiz Посмотреть сообщение
Ну как же!?
Данный момент (декомпозиция массива) был унаследован из языка Си, в стандарте которого я более-менее разбираюсь. Дальше речь пошла о ссылках, которые есть только в Си++. И в этом я разбираюсь плохо, хотя немного пораскинув мозгами пришёл к выводу: Возвращение ссылки на локальный объект



Цитата Сообщение от ValeryS Посмотреть сообщение
Assembler
1
2
3
4
ax--адрес 
bx--смещение 
add ax,bx
mov dx[ax]
что соответствует
*(a + b*sizeof(type))
Только в твоём ассемблерном фрагменте нету sizeof'а

Цитата Сообщение от diagon Посмотреть сообщение
Вообще, по стандарту, y[x] означает *(y + x)
Только если копать дальше, то *(y + x) при переходе в абсолютные значения адресов означает чтение из адреса y + x * sizeof(*y)
ValeryS
Модератор
6413 / 4879 / 448
Регистрация: 14.02.2011
Сообщений: 16,180
15.05.2012, 18:45     Почему работает и так, и так: arr[i] и i[arr]? #23
Цитата Сообщение от Evg Посмотреть сообщение
Только в твоём ассемблерном фрагменте нету sizeof'а
разумеется нет это же так пример
для char смешение bx
для short add bx,bx
для int add ebx,ebx add ebx,ebx
тоже самое сдвигами
в 32 разрадном вообще лафа
C++
1
2
3
lea edx,[eax+ebx]
lea edx,[eax+ebx*2]
lea edx,[eax+ebx*4]
вообще то я хотел показать
что
Assembler
1
2
add ax,bx
mov dx,[ax]
и
Assembler
1
2
add bx,ax
mov dx,[bx]
это одно и тоже
из за слабости компиляторов это и перешло в С(мое мнение)
а потом не стали убирать для совместимости
diagon
Higher
 Аватар для diagon
1921 / 1187 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
15.05.2012, 19:18     Почему работает и так, и так: arr[i] и i[arr]? #24
Цитата Сообщение от Evg Посмотреть сообщение
Только если копать дальше, то *(y + x) при переходе в абсолютные значения адресов означает чтение из адреса y + x * sizeof(*y)
Необязательно.
C++
1
2
3
4
int *a;
int b;
*(a + b); 
*(b + a);
Зависит от того, что суммируется. Если указатель с целым, как в моем примере, то формула будет
[указатель] + [целое] * sizeof( *[указатель] );
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16943 / 5348 / 329
Регистрация: 30.03.2009
Сообщений: 14,383
Записей в блоге: 26
15.05.2012, 19:56     Почему работает и так, и так: arr[i] и i[arr]? #25
Цитата Сообщение от ValeryS Посмотреть сообщение
в 32 разрадном вообще лафа
C++
1
2
3
lea edx,[eax+ebx]
lea edx,[eax+ebx*2]
lea edx,[eax+ebx*4]
Ну очевидно же, что это НЕ коммутативно относительно eax и ebx

Цитата Сообщение от ValeryS Посмотреть сообщение
вообще то я хотел показать
что
Assembler
1
2
add ax,bx
mov dx,[ax]
и
Assembler
1
2
add bx,ax
mov dx,[bx]
это одно и тоже
Одно и то же только в случае указателя на char

Цитата Сообщение от ValeryS Посмотреть сообщение
из за слабости компиляторов это и перешло в С(мое мнение)
а потом не стали убирать для совместимости
Наврядли. Поддержать оптимально такую конструкцию - это мизерная правка в компиляторе. Другое дело, что у куривших было ассемблерное мышление, а потому такую хрень внесли в язык. Т.е. причина с точностью до наоборот

Цитата Сообщение от diagon Посмотреть сообщение
Необязательно
Блин, реально даже логично получается...
castaway
Эксперт С++
4867 / 3006 / 370
Регистрация: 10.11.2010
Сообщений: 11,056
Записей в блоге: 10
Завершенные тесты: 1
16.05.2012, 00:56     Почему работает и так, и так: arr[i] и i[arr]? #26
О чем спорим, парни!?
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
20.12.2012, 18:38     Почему работает и так, и так: arr[i] и i[arr]? #27
Цитата Сообщение от Bers Посмотреть сообщение
Нет. Не так. Это - массив. Который компилятор имеет право не явно приводить к типу указателя
Нет. arr - это массив, реализуемый с помощью указателя. Именно так. О том, что это массив знают люди и sizeof, в остальных случаях это указатель. Мало того,
C++
1
2
3
int *p;
int i;
p[i] /* i-й элемент массива, на который указывает p, таким образом, указатель на массив и на его нулевой элемент - одно и тоже*/
.

Добавлено через 2 минуты
Например,
C++
1
2
3
4
int a[30];
    int *p;
    p=&a[4];
    p[3]=16;//16 присваивается седьмому элементу a
.

Добавлено через 39 минут
Цитата Сообщение от Evg Посмотреть сообщение
/* При вычислении адреса *используется формула a + i * sizeof (int)*/
a[i];
/* При вычислении адреса *используется та же формула a + i * sizeof (int),
** но не i + a * sizeof (int). Так что правило коммутативности тут не используется
** (т.к. выражения НЕ симметричны) */
Нет. То, что на низком уровне есть умножение, ничего не значит, формула здесь a+i безо всяких * sizeof (int). Да, само сложение перегружено на сложение не со слагаемым, а с его произведением на sizeof. Но это внутри оператора, а не в выражении. И некоммутативность здесь не причём, асимметрия суммы проистекает из разнотипности слагаемых: указатель и size_t. От их переставновки приходим просо к другой операции, которая перегружена прямо противоположным образом. Но если так и написать i+a, то выглядит это как обычная сумма чисел и от перестановки результат меняться не должен. Он и не меняется. Но скобки - это другой синтаксис и как сложение они не выглядят.

Добавлено через 3 минуты
В случае скобок это снижает читабельность, так как не говорит о том, где здесь индекс, а где указатель. Другое дело сумма с указателем, там адресная арифметика.

Добавлено через 1 минуту
И там не имеет значения где что.
yekka
384 / 148 / 8
Регистрация: 12.05.2011
Сообщений: 450
22.12.2012, 16:17     Почему работает и так, и так: arr[i] и i[arr]? #28
Цитата Сообщение от taras atavin Посмотреть сообщение
arr - это массив, реализуемый с помощью указателя

расскажи-ка, пожалуйста, как массив (т.е. область памяти) можно "реализовать" указателем?

Добавлено через 2 часа 57 минут
1. Массив данных -- это область памяти, в которой хранятся данные.
2. Указатель на данные -- это область памяти, в которой хранится адрес, по которому можно найти данные.

То, что имя массива данных легко неявно конвертируется в указатель на данные, конечно, запутывает новичков. Но когда тебе говорят, что ты не прав и говорят, что это разные вещи, то не надо спорить, надо мотать на ус.
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16943 / 5348 / 329
Регистрация: 30.03.2009
Сообщений: 14,383
Записей в блоге: 26
22.12.2012, 16:47     Почему работает и так, и так: arr[i] и i[arr]? #29
Цитата Сообщение от UI Посмотреть сообщение
Потому что "от перемены мест слагаемых сумма не изменяется". Что такое arr[ i ]? Это arr + i. Так какая разница, что с чем складывать, arr+i или i+arr?
Цитата Сообщение от diagon Посмотреть сообщение
Вообще, по стандарту, y[x] означает *(y + x)
Ну и в продолжение можно сказать, что к элементам двумерного массива можно обращаться так:

C
1
2
3
4
5
6
7
int x[3][3];
int i;
int j;
 
...
/* эквиdалентно a = x[j][i] */
a = i[j[x]];
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
22.12.2012, 16:50     Почему работает и так, и так: arr[i] и i[arr]?
Еще ссылки по теме:

C++ Объявление массива int *arr почему так
C++ синонимы операций взятия адреса массива (arr и &arr)
чем отличается *(arr+1) от *(arr++)? C++
C++ Не понимаю, что не так, почему не работает
C++ Объяснить почему sizeof(arr) всегда возвращает одно и то же значение

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Second
79 / 80 / 1
Регистрация: 10.08.2011
Сообщений: 665
22.12.2012, 16:50     Почему работает и так, и так: arr[i] и i[arr]? #30
Цитата Сообщение от UI Посмотреть сообщение
Потому что "от перемены мест слагаемых сумма не изменяется". Что такое arr[ i ]? Это arr + i. Так какая разница, что с чем складывать, arr+i или i+arr?
лол зашквар )))



я помню даже такое правило в С++ синтаксис описания массива верен в обоих случаях. Просто так реализовано.
Yandex
Объявления
22.12.2012, 16:50     Почему работает и так, и так: arr[i] и i[arr]?
Ответ Создать тему
Опции темы

Текущее время: 11:26. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru