Форум программистов, компьютерный форум, киберфорум
Наши страницы

C++

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 42, средняя оценка - 4.90
ForwardM
1 / 1 / 0
Регистрация: 14.05.2012
Сообщений: 5
#1

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

14.05.2012, 21:20. Просмотров 5761. Ответов 29
Метки нет (Все метки)

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;
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
14.05.2012, 21:20
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Почему работает и так, и так: arr[i] и i[arr]? (C++):

Почему С++ так востребован? - C++
Подскажите, почему С++ так востребован? Я думаю синтаксис удобнее у СШарп чем у С++. Да и С++ вроде бы как уже устаревший язык...

Множественное наследование - так ли это плохо? - C++
Вопрос не в том, что это такое и пр. С момента изучения Си++ во всех книжках все авторы (кроме самого Страуструпа) пишут, что множественное...

OpenGL что не так в коде? вроде все нормально - C++
Собственно вот код, я сижу под убунтой 9.10 и он ругаеться пишет #include&lt;GL/glut.h&gt; int N = 3; int n = 0; int x; int y; ...

Мусорное значение в динамическом массиве в структуре. Что я делаю не так? - C++
Здравствуйте! Делаю вычисление факториала от 21 до 30. Использую длинную арифметику. Произведение длинного и короткого чисел -...

Как сделать так чтобы простейшая программа запускалась сначало - C++
Предположим есть самая простая программа: #include &lt;iostream&gt; using namespace std; #include &lt;cmath&gt; int main() { double c; ...

Баг или так задумано? Фишка с кодировкой файлов компиляции - C++
Visual C++ 2013 Express. От изменения кодировки созданных .cpp файлов будет зависеть то как выводятся русские буквы. Никогда раньше не...

29
castaway
Эксперт С++
4915 / 3023 / 370
Регистрация: 10.11.2010
Сообщений: 11,081
Записей в блоге: 10
Завершенные тесты: 1
14.05.2012, 23:50 #16
Цитата Сообщение от Evg Посмотреть сообщение
Хз, я как-то в Си++ не сильно разбираюсь. ...
Ну как же!?
Цитата Сообщение от Evg Посмотреть сообщение
Это именно в стандарте такая гадость прописана.
0
Avazart
Эксперт С++
7247 / 5419 / 297
Регистрация: 10.12.2010
Сообщений: 24,048
Записей в блоге: 17
15.05.2012, 01:23 #17
То есть суть в том что неплохо было бы, чтоб компилятор ругался при возврате по ссылке не static переменных стандартных типов?
0
ValeryS
Модератор
6709 / 5118 / 482
Регистрация: 14.02.2011
Сообщений: 17,211
15.05.2012, 01:47 #18
Цитата Сообщение от Evg Посмотреть сообщение
Потому что авторам Си такое взбрело в голову. Логики кривой конструкции я не понимаю, нормального объяснения нигде не видел. Хз может они курили, а может просто гениями были и нам их не понять
скорее всего чтобы быть поближе к ассемблеру
когда писали язык машины были очень слабые
для х86(для 80 тоже, регистры другие)
Assembler
1
2
3
4
ax--адрес 
bx--смещение 
add ax,bx
mov dx[ax]
что соответствует
*(a + b*sizeof(type))
за ассемблеры других фирм не скажу знаю только интел
1
Jupiter
15.05.2012, 02:05
  #19
 Комментарий модератора 
Прекращаем оффтоп!
0
diagon
Higher
1930 / 1196 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
15.05.2012, 08:21 #20
Вообще, по стандарту, y[x] означает *(y + x)
2
ForwardM
1 / 1 / 0
Регистрация: 14.05.2012
Сообщений: 5
15.05.2012, 08:37  [ТС] #21
Всем большое спасибо.
0
Evg
Эксперт CАвтор FAQ
18253 / 6378 / 438
Регистрация: 30.03.2009
Сообщений: 17,656
Записей в блоге: 28
15.05.2012, 08:49 #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)
0
ValeryS
Модератор
6709 / 5118 / 482
Регистрация: 14.02.2011
Сообщений: 17,211
15.05.2012, 18:45 #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]
это одно и тоже
из за слабости компиляторов это и перешло в С(мое мнение)
а потом не стали убирать для совместимости
0
diagon
Higher
1930 / 1196 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
15.05.2012, 19:18 #24
Цитата Сообщение от Evg Посмотреть сообщение
Только если копать дальше, то *(y + x) при переходе в абсолютные значения адресов означает чтение из адреса y + x * sizeof(*y)
Необязательно.
C++
1
2
3
4
int *a;
int b;
*(a + b); 
*(b + a);
Зависит от того, что суммируется. Если указатель с целым, как в моем примере, то формула будет
[указатель] + [целое] * sizeof( *[указатель] );
2
Evg
Эксперт CАвтор FAQ
18253 / 6378 / 438
Регистрация: 30.03.2009
Сообщений: 17,656
Записей в блоге: 28
15.05.2012, 19:56 #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 Посмотреть сообщение
Необязательно
Блин, реально даже логично получается...
0
castaway
Эксперт С++
4915 / 3023 / 370
Регистрация: 10.11.2010
Сообщений: 11,081
Записей в блоге: 10
Завершенные тесты: 1
16.05.2012, 00:56 #26
О чем спорим, парни!?
0
taras atavin
3570 / 1753 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
20.12.2012, 18:38 #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 минуту
И там не имеет значения где что.
0
yekka
386 / 150 / 8
Регистрация: 12.05.2011
Сообщений: 450
22.12.2012, 16:17 #28
Цитата Сообщение от taras atavin Посмотреть сообщение
arr - это массив, реализуемый с помощью указателя

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

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

То, что имя массива данных легко неявно конвертируется в указатель на данные, конечно, запутывает новичков. Но когда тебе говорят, что ты не прав и говорят, что это разные вещи, то не надо спорить, надо мотать на ус.
0
Evg
Эксперт CАвтор FAQ
18253 / 6378 / 438
Регистрация: 30.03.2009
Сообщений: 17,656
Записей в блоге: 28
22.12.2012, 16:47 #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]];
1
Second
79 / 80 / 1
Регистрация: 10.08.2011
Сообщений: 665
22.12.2012, 16:50 #30
Цитата Сообщение от UI Посмотреть сообщение
Потому что "от перемены мест слагаемых сумма не изменяется". Что такое arr[ i ]? Это arr + i. Так какая разница, что с чем складывать, arr+i или i+arr?
лол зашквар )))



я помню даже такое правило в С++ синтаксис описания массива верен в обоих случаях. Просто так реализовано.
0
22.12.2012, 16:50
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
22.12.2012, 16:50
Привет! Вот еще темы с ответами:

Выручите сделайте данное задание так-как я в с++ не очень силен - C++
1 задание: В матриці В знайти суму елементів, що лежать вище головної діагоналі.(Изображение матрицы загрузил матрица В) 2 задание:...

Как сделать так, чтобы в окне, созданом OpenGL, рисовали 2 потока? - C++
Вот не знаю, где создать тему, с одной стороны это надо в разделе OpenGL, с другой стороны- там чисто художники, а здесь именно...

Обьясниете, почему программа В С++ так работает. - C++ Builder
Данная программа выводит единицы и нули в шахматном порядке,10 строк и 10 столбцов. но если изменить значение, которые будут выводиться...

Почему не работает так как надо - C++ Builder
#include &lt;vcl.h&gt; #pragma hdrstop #include &quot;Unit1.h&quot; //--------------------------------------------------------------------------- ...


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

Или воспользуйтесь поиском по форуму:
30
Ответ Создать тему
Опции темы

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