Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 12, средняя оценка - 4.75
Aqua77
25 / 25 / 19
Регистрация: 13.07.2015
Сообщений: 433
#1

Почему при присваивании адреса массива не ставится знак '&' получения адреса - C++

22.11.2015, 21:01. Просмотров 2165. Ответов 88
Метки нет (Все метки)

C++
1
2
3
4
5
6
7
8
9
10
int main()
{
    int a[2] = { 2, 3 };
    int* b;
    b = a; //Почему при присваивании адреса массива не ставится знак '&' получения адреса.
//А когда присваиваешь адрес отдельной переменной, то необходимо ставить этот знак.
//int a=2;
    int* b;
    b = &a;//
}
И ещё адрес массива из пяти элементов передаст указателю все пять элементов? От адреса первого [0] до адреса последнего [4]. То есть, после такого присвоения указатель будет иметь все 5 адресов?
http://www.cyberforum.ru/cpp-beginners/thread1323199.html
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
22.11.2015, 21:01
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Почему при присваивании адреса массива не ставится знак '&' получения адреса (C++):

Почему разные адреса одного и того же элемента динамического массива?
Я создаю динамический массив и отправляю его в функцию, если потом сравнивать...

Синонимы операций взятия адреса массива (arr и &arr)
возможно коряво написал заголовок, да и сам вопрос банальный. после создании...

[Указатели]Использование операции получения адреса операнда
Здравствуйте! Объясните пожалуйста, почему в пером случае, когда присваиваем...

Почему при выводе односвязного списка на экран он выдаёт ещё какие-то дополнительные адреса?
Здравствуйте, помогите пожалуйста разобраться, почему при выводе односвязного...

Оператор взятия адреса (&)
while (true) { int *temp = new int(13); std::cout << temp << " ";...

88
fitochay
14 / 14 / 1
Регистрация: 14.03.2015
Сообщений: 113
22.11.2015, 21:07 #2
В C++ использование имени массива без индекса образует указатель на первый элемент массива.
Вот
0
Байт
Эксперт C
17763 / 11788 / 2449
Регистрация: 24.12.2010
Сообщений: 23,706
22.11.2015, 21:57 #3
Цитата Сообщение от Aqua77 Посмотреть сообщение
Почему при присваивании адреса массива не ставится знак '&' получения адреса
Массив - он уже сам адрес.
Упрощенно так. int mass[2] создает кусок памяти для хренения 2-х целых и переменную - адрес этой памяти. (эксперты, возможно. скажут, что это не совсем так, но тебе лучше сейчас представлять дело именно таким образом). Так что mass - это уже указатель(адрес). Присваивание int *b = mass имеет дело с сущностями одной природы.
Цитата Сообщение от Aqua77 Посмотреть сообщение
//А когда присваиваешь адрес отдельной переменной, то необходимо ставить этот знак.
Надеюсь, из вышеизложенного все уже понятно.
Цитата Сообщение от Aqua77 Посмотреть сообщение
И ещё адрес массива из пяти элементов передаст указателю все пять элементов?
Конечно нет! Он дает указатель только на первый элемент (адрес, где начинается массив). А про его длину он ничего не знает и знать не хочет. И в этом все прелести и все опасности языка Си.
Цитата Сообщение от Aqua77 Посмотреть сообщение
То есть, после такого присвоения указатель будет иметь все 5 адресов?
Надеюсь, что ответ на этот вопро уже понятен. Но доступ ко всем пяти элементам построен.
*b, *(b+4), *(b+100) - а вот тут ты уже обращаешься неизвестно куда. И программа твоя крашится.
Кстати, надо понять, что &a[5] абсолютно тоже самое, что и *(a+5)
1
Croessmah
++Ͻ
14158 / 8083 / 1513
Регистрация: 27.09.2012
Сообщений: 19,919
Записей в блоге: 3
Завершенные тесты: 1
22.11.2015, 22:02 #4
Цитата Сообщение от Байт Посмотреть сообщение
ак что mass - это уже указатель(адрес).
Он неявно приводится к указателю на первый элемент.
Если бы "b" была указателем на массив, то пришлось бы использовать "&" для взятия адреса массива:
C++
1
2
    int a[2] = { 2, 3 };
    int(*b)[2] = &a;
1
Байт
22.11.2015, 22:08
  #5

Не по теме:

Цитата Сообщение от Croessmah Посмотреть сообщение
Если бы "b" была указателем на массив,
Слушай, не путай парня, а? Ты еще расскажи ему чем указатель на указатель на указатель отличается от просто указателя на указатель. И так - рекурсивно, пока голова не закружится. А ведь похоже, человек и правда пытается разобраться. Вот разберется - он тебе покажет, кошаку вредному

0
Croessmah
22.11.2015, 22:16
  #6

Не по теме:

Цитата Сообщение от Байт Посмотреть сообщение
Слушай, не путай парня, а?
Ок. Тогда еще покажем ссылку на массив:
C++
1
2
    int a[2] = { 2, 3 };
    int(&b)[2] = a;
Я ж вредный
Вот разберется - он тебе покажет, кошаку вредному
да ладно, я ж как лучше

0
Apparat_UA
5 / 5 / 2
Регистрация: 06.01.2015
Сообщений: 175
22.11.2015, 22:36 #7
В случае с массивом, его имя является указателем. На самом деле такой формат mas[i] упрощение такого *(mas+i). Если просто написать *mas, то будем ссылаться на первый элемент так как *(mas+0). В памяти элементы массива распределяются друг за другом, компилятор определяет какого типа данные в массиве и когда мы пишем *(mas+i), он как бы доумножает это i на кол-во байт, выделяемых под каждый элемент. Если массив целых чисел, адреса будут отличать на 4 байта. Так суммируя адреса он доходит до нужного и просто разыменовывает его. То есть, если писать mas+i мы будем получать адреса элементов, что эквивалентно &mas[i].
0
Croessmah
++Ͻ
14158 / 8083 / 1513
Регистрация: 27.09.2012
Сообщений: 19,919
Записей в блоге: 3
Завершенные тесты: 1
22.11.2015, 22:39 #8
Цитата Сообщение от Apparat_UA Посмотреть сообщение
В случае с массивом, его имя является указателем.
пост 4!
1
Apparat_UA
5 / 5 / 2
Регистрация: 06.01.2015
Сообщений: 175
22.11.2015, 23:03 #9
Цитата Сообщение от Croessmah Посмотреть сообщение
Он неявно приводится к указателю на первый элемент.
Если бы "b" была указателем на массив, то пришлось бы использовать "&" для взятия адреса массива
Спасибо. Где можно поподробнее почитать об этом ?
0
Байт
Эксперт C
17763 / 11788 / 2449
Регистрация: 24.12.2010
Сообщений: 23,706
22.11.2015, 23:20 #10
Цитата Сообщение от Apparat_UA Посмотреть сообщение
Где можно поподробнее почитать об этом ?
Цитата Сообщение от Croessmah Посмотреть сообщение
Он неявно приводится к указателю на первый элемент.
Вечер поздний, спать неохота, а делать нечего. Давай попробуем этот момент разжевать. Пока кашей не станет.
На все объявленные в функции переменные (и параметры тож) в памяти выделяется некоторая область (стек называется, но - не суть). И в странслированной функции этот адрес есть (ей известен). И поэтому известны ей адреса всех переменных. Вот "int *b" выделяет кусочек памяти. А "int mass[2]" выделяет память только на массив. А указатель на этот массив ей не нужен. Он известен. Он - константа. И просто присутствует как таковая в сгенерированных командах. Вот и все. И самое сложное - это понять, что на самом деле все чрезвычайно просто
3
Croessmah
++Ͻ
14158 / 8083 / 1513
Регистрация: 27.09.2012
Сообщений: 19,919
Записей в блоге: 3
Завершенные тесты: 1
22.11.2015, 23:25 #11
Apparat_UA, можно почитать тему, начиная с сообщения http://www.cyberforum.ru/cpp-beginners/thread32490.html#post7893074
1
Байт
22.11.2015, 23:39
  #12

Не по теме:

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

0
Aqua77
25 / 25 / 19
Регистрация: 13.07.2015
Сообщений: 433
23.11.2015, 10:07  [ТС] #13
Цитата Сообщение от Байт Посмотреть сообщение
&a[5] абсолютно тоже самое, что и *(a+5)
&a[5] - это адрес 6-го элемента а *(a+5) Значение элемента?

Добавлено через 15 минут
Цитата Сообщение от Apparat_UA Посмотреть сообщение
компилятор определяет какого типа данные в массиве и когда мы пишем *(mas+i), он как бы доумножает это i на кол-во байт, выделяемых под каждый элемент.
То есть если массив типа int, и я хочу обратится к 5-тому элементу компилятор зная что один элемент типа int содержит 4 байта умножает 4 на 5.
0
Tulosba
:)
Эксперт С++
4746 / 3240 / 496
Регистрация: 19.02.2013
Сообщений: 9,046
23.11.2015, 10:41 #14
Цитата Сообщение от Aqua77 Посмотреть сообщение
&a[5] - это адрес 6-го элемента а *(a+5) Значение элемента?
Да. Только для исключения путаницы, предпочтительнее писать не "6-го элемента", а "элемента с индексом 5", имхо.
Цитата Сообщение от Aqua77 Посмотреть сообщение
компилятор зная что один элемент типа int содержит 4 байта умножает 4 на 5.
Снова да Именно поэтому опасно в указателе на базовый класс хранить адрес начала массива класса производного.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
 
struct B {
    int i;
};
 
struct D : B {
    int j;
};
 
int main()
{
    D d[3];
    
    d[0].i = 1;
    d[0].j = 2;
    
    d[1].i = 3;
    d[1].j = 4;    
    
    d[2].i = 5;
    d[2].j = 6; 
    
    B* b = d; 
 
    std::cout << b[0].i << std::endl; // 1, ok
 
    std::cout << b[1].i << std::endl; // 2, но хотели бы 3
    
    std::cout << b[2].i << std::endl; // 3, но хотели бы 5   
}
http://coliru.stacked-crooked.com/a/d3dd451d7731aee2
0
Croessmah
23.11.2015, 11:58
  #15

Не по теме:

Цитата Сообщение от Байт Посмотреть сообщение
На первой лекции рассказать о чрезвычайной простоте и убогости вычислительной машины. О том, что она умеет делать только очень примитивные операции. И только то, что этих операций миллионы и выполняются они со скоростью миллиардов в секунду делает наш мир столь "прекрасным"
Поздно. В какой-то книге я уже видел этот подход

0
gru74ik
Модератор
Эксперт CЭксперт С++
4648 / 1962 / 293
Регистрация: 20.02.2013
Сообщений: 5,225
Записей в блоге: 23
23.11.2015, 12:37 #16
Aqua77, у Дейтелов в книжке "Как программировать на C++" (2008), в 8 главе (стр. 534):
Цитата Сообщение от Харви М. Дейтела и Пола Дж. Дейтела
Предположим, сделаны следующие объявления:
C++
1
2
int b[5]; // создать 5-элементный целый массив b
int *bPtr; // создать указатель на целое bPtr
Так как имя массива (без индекса) является указателем (константным) на его
первый элемент, мы можем присвоить указателю bPtr адрес первого элемента
массива b при помощи оператора присваивания
C++
1
bPtr = b;
Этот оператор эквивалентен следующему, в котором используется операция
взятия адреса первого элемента массива:
C++
1
bPtr = &b[0];
Альтернативный способ ссылки на элемент массива b[3], использующий
выражение с указателем, представлен в следующем операторе:
C++
1
*(bPtr + 3)
0
Croessmah
++Ͻ
14158 / 8083 / 1513
Регистрация: 27.09.2012
Сообщений: 19,919
Записей в блоге: 3
Завершенные тесты: 1
23.11.2015, 12:40 #17
Цитата Сообщение от gru74ik Посмотреть сообщение
Так как имя массива (без индекса) является указателем (константным) на его
первый элемент
еще раз:
4.2 Array-to-pointer conversion
1. An lvalue or rvalue of type “array of N T” or “array of unknown bound of T” can be converted to a prvalue of type “pointer to T”. The result is a pointer to the first element of the array.
0
gru74ik
Модератор
Эксперт CЭксперт С++
4648 / 1962 / 293
Регистрация: 20.02.2013
Сообщений: 5,225
Записей в блоге: 23
23.11.2015, 13:19 #18
Croessmah, то есть, у Дейтелов ошибка?
0
daslex
23.11.2015, 13:30
  #19

Не по теме:

У переводчиков ошибка скорее всего. Надо в оригинале смотреть для подстраховки. Там много очепяток и неточностей.

0
gru74ik
Модератор
Эксперт CЭксперт С++
4648 / 1962 / 293
Регистрация: 20.02.2013
Сообщений: 5,225
Записей в блоге: 23
23.11.2015, 13:41 #20
Или, скажем так, упрощение?

Добавлено через 10 минут
У Праты вот:
Цитата Сообщение от Стивен Прата
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// addpntrs.cpp -- pointer addition
#include <iostream>
int main()
{
    using namespace std;
    double wages[3] = {10000.0, 20000.0, 30000.0};
    short stacks[3] = {3, 2, 1};
 
// Here are two ways to get the address of an array
    double * pw = wages;     // name of an array = address
    short * ps = &stacks[0]; // or use address operator
// with array element
    cout << "pw = " << pw << ", *pw = " << *pw << endl;
    pw = pw + 1;
    cout << "add 1 to the pw pointer:\n";
    cout << "pw = " << pw << ", *pw = " << *pw << "\n\n";
 
    cout << "ps = " << ps << ", *ps = " << *ps << endl;
    ps = ps + 1;
    cout << "add 1 to the ps pointer:\n";
    cout << "ps = " << ps << ", *ps = " << *ps << "\n\n";
 
    cout << "access two elements with array notation\n";
    cout << "stacks[0] = " << stacks[0] 
         << ", stacks[1] = " << stacks[1] << endl;
    cout << "access two elements with pointer notation\n";
    cout << "*stacks = " << *stacks
         << ", *(stacks + 1) =  " << *(stacks + 1) << endl;
 
    cout << sizeof(wages) << " = size of wages array\n";
    cout << sizeof(pw) << " = size of pw pointer\n";
    // cin.get();
    return 0; 
}
В большинстве контекстов C++ интерпретирует имя массива как адрес его
первого элемента. Таким образом, следующий оператор создает pw как указатель на тип
double, затем инициализирует его wages, который также является адресом первого
элемента массива wages:
C++
1
double * pw = wages;
Для wages, как и любого другого массива, справедливо следующее утверждение:
C++
1
wages = &wages[0] = адрес первого элемента массива
0
23.11.2015, 13:41
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
23.11.2015, 13:41
Привет! Вот еще темы с решениями:

Почему выводит адреса?
Всем привет! Программа работает, но почему то выводит данные вместе с адресом...

Почему адреса одинаковые?
Обьясните пожалуйста код, почему адреса одинаковые? #include &lt;iostream&gt;...

Почему указатели имеют одинаковые адреса
Например, если взять указатели на массивы. **m имеет тот же адрес, что и *m,...

Почему выводит адреса, а не значения? Это часть программы
Лабораторная работа, должны выводиться значения массива, но выводятся адреса


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

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

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