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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 12, средняя оценка - 4.75
Aqua77
25 / 25 / 16
Регистрация: 13.07.2015
Сообщений: 431
#1

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

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

Операция получения адреса & и vector - C++
Здравствуйте. Работает ли Операция получения адреса (&) в векторе? Просто есть пример в книги, но про вектор ничего не сказано....

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

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

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

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

Оператор взятия адреса (&) - C++
while (true) { int *temp = new int(13); std::cout << temp << " "; std::cout << &temp << std::endl; } Создаю каждый раз...

88
gru74ik
Модератор
Эксперт CЭксперт С++
4168 / 1816 / 198
Регистрация: 20.02.2013
Сообщений: 4,953
Записей в блоге: 21
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
Эксперт CЭксперт С++
13409 / 7559 / 853
Регистрация: 27.09.2012
Сообщений: 18,601
Записей в блоге: 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Эксперт С++
4168 / 1816 / 198
Регистрация: 20.02.2013
Сообщений: 4,953
Записей в блоге: 21
23.11.2015, 13:19 #18
Croessmah, то есть, у Дейтелов ошибка?
0
daslex
23.11.2015, 13:30
  #19

Не по теме:

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

0
gru74ik
Модератор
Эксперт CЭксперт С++
4168 / 1816 / 198
Регистрация: 20.02.2013
Сообщений: 4,953
Записей в блоге: 21
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
daslex
1271 / 515 / 106
Регистрация: 02.08.2011
Сообщений: 2,706
23.11.2015, 13:42 #21
Это не упрощение. В русском варианте цитаты Дейтелов грубая ошибка.
Имя массива - не является ни указателем, ни ссылкой, ни чем-либо еще. Это вообще не объект какого бы-то ни было типа, это идентификатор типа NoType и стандарт разрешает это "чудо-юдо" приводить к типу константный указатель.
Только благодаря неявному приведению, с ним возможно работать как с константным указателем.
0
gru74ik
Модератор
Эксперт CЭксперт С++
4168 / 1816 / 198
Регистрация: 20.02.2013
Сообщений: 4,953
Записей в блоге: 21
23.11.2015, 13:58 #22
Блин, про неявное приведение к указателю чё-то никто не пишет. Вот, ещё, например в "Эффективное программирование на C++":
Цитата Сообщение от Эндрю Кёниг и Барбара Му
Независимо от того, как мы определим массив, всегда существует следующее
фундаментальное соотношение между массивами и указателями: всякий раз когда мы
используем имя массива как значение, это имя представляет собой указатель на начальный
элемент массива (первое фундаментальное свойство массивов).
Добавлено через 5 минут
И далее (стр. 212) там же:
Цитата Сообщение от Эндрю Кёниг и Барбара Му
Как упоминалось в разделе 10.1.3, имя массива является адресом начального элемента этого массива.
0
daslex
23.11.2015, 14:00
  #23

Не по теме:

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

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

0
gru74ik
Модератор
Эксперт CЭксперт С++
4168 / 1816 / 198
Регистрация: 20.02.2013
Сообщений: 4,953
Записей в блоге: 21
23.11.2015, 14:06 #24
Цитата Сообщение от daslex Посмотреть сообщение
Неужто кредит доверия оригиналу библии С++ меньше чем кредит доверия русским переводам из разных источников, которые не стандарт языка???
Да нет, не меньше, конечно. Просто почти все учебники во весь голос одно и то же кричат. Странно как-то.
0
Voivoid
675 / 278 / 12
Регистрация: 31.03.2013
Сообщений: 1,339
23.11.2015, 14:08 #25
Цитата Сообщение от daslex Посмотреть сообщение
Это вообще не объект какого бы-то ни было типа, это идентификатор типа NoType и стандарт разрешает это "чудо-юдо" приводить к типу константный указатель
Ого, это что-то новенькое
0
Tulosba
:)
Эксперт С++
4396 / 3232 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
23.11.2015, 14:20 #26
Цитата Сообщение от gru74ik Посмотреть сообщение
Просто почти все учебники во весь голос одно и то же кричат. Странно как-то.
Ничего странного. Просто учебник пишется более понятным языком, а не сухим языком Стандарта.
Именно поэтому, учить язык по Стандарту - занятие не благодарное, но и утверждать, что книги врут тоже нельзя, т.к. с обывательской (прикладного программиста) точки зрения имя массива есть указатель на начальный элемент.
А вот когда хочется узнать как (почему) это работает уже есть смысл заглянуть в Стандарт.
0
gru74ik
Модератор
Эксперт CЭксперт С++
4168 / 1816 / 198
Регистрация: 20.02.2013
Сообщений: 4,953
Записей в блоге: 21
23.11.2015, 14:21 #27
Вот ещё и Липпман сотоварищи в "Язык программирования C++. Базовый курс" (2014) туда же (стр. 167):
Цитата Сообщение от Стенли Б. Липпман, Жози Лажойе, Барбара Э. Му
Существует множество свидетельств того факта, что операции с массивами зачастую являются операциями с указателями. Одно из них - при использовании массива как инициализатора переменной, определённой с использованием спецификатора auto (см. раздел 2.5.2, стр.107), выводится тип указателя, а не массива.
C++
1
2
int ia[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; // ia - массив из 10 целых чисел
auto ia2(ia); // ia2 - это int*, указывающий на первый элемент в ia
0
daslex
1271 / 515 / 106
Регистрация: 02.08.2011
Сообщений: 2,706
23.11.2015, 15:03 #28
Посмотрел русский, не ленись посмотреть оригинальный текст в оригинальном учебнике.
Вот я не поленился. Отрыл оригинал Дейтелов (7изд). Красиво там все, красочно так.

оригинал текста
Arrays and pointers are intimately related in C++ and may be used almost interchangeably.
An array name can be thought of as a constant pointer
Перевод текста
Массивы и указатели тесно связаны в C ++ и могут использоваться как синонимы.
Имя массива можно рассматривать в качестве константного указателя
Заметь, что ни разу не сказано о том, что это указатель. В оригиналах других популярных книг наверняка так же. Это твердолобые переводчики косячят не по-детски. А мы страдаем.

Добавлено через 4 минуты
А дальше уже пример, что они тесно связаны.

C++
1
2
int b[ 5 ]; // create 5-element int array b
int *bPtr; // create int pointer bPtr
Добавлено через 2 минуты
Хотя дальше и говорится...
Because the array name (without a subscript) is a (constant) pointer to the first element of the array, we can set bPtr to the address of the first element in array b with the statement
ошибочно в оригинале

Добавлено через 11 минут
Дейтелы немного подофигели такую ересь писать
Although array names are pointers to the beginning of the array, array names cannot be
modified in arithmetic expressions, because array names are constant pointers.
Это однозначно ошибка авторов. Они как бы и рассматривают их как указатели, только не оговорили этого явно. Вот только в этом у них тут ошибка.
1
gru74ik
Модератор
Эксперт CЭксперт С++
4168 / 1816 / 198
Регистрация: 20.02.2013
Сообщений: 4,953
Записей в блоге: 21
24.11.2015, 06:31 #29
daslex, я думаю, это общее место в большинстве обучающих книг по С++. Упрощение. Да, они грешат против истины, но так проще объяснить новичку. Они говорят о том, что это указатель, но не упоминают о том, что получается он из неявного преобразования имени массива в указатель на первый элемент. Иначе придётся ещё тут же пояснять, что такое преобразования, чем явные преобразования отличаются от неявных и т.д. А в теме про массивы и указатели новичку и так непросто разобраться.

Добавлено через 10 минут
У Страуструпа так:
Цитата Сообщение от Bjarne Stroustrup
In C++, pointers and arrays are closely related. The name of an array can be used as a pointer to its initial element. For example:
C++
1
2
intv[] = {1, 2, 3, 4};
int* p1 = v; // pointer to initial element (implicit conversion)
Цитата Сообщение от Бьярне Страуструп
В языке C++ указатели и массивы тесно связаны. Имя массива может быть использовано в качестве указателя на его первый элемент. Например:
C++
1
2
intv[] = {1, 2, 3, 4};
int* p1 = v; //указатель на начальный элемент (неявное преобразование)
Добавлено через 7 минут
И далее у него же:
Цитата Сообщение от Bjarne Stroustrup
The implicit conversion of an array name to a pointer to the initial element of the array is extensively used in function calls in C-style code.
Цитата Сообщение от Бьярне Страуструп
Неявные преобразования имени массива в указатель на его первый элемент широко используются при вызовах функций в С-стиле.
1
mporro
256 / 101 / 14
Регистрация: 04.07.2014
Сообщений: 571
24.11.2015, 08:55 #30
Всё, что неявно куда-то приводится является этим куда-то.
Метафорически говоря, типовая метка указателя int* -- базовый тип для типа переменной а, объявленной как int a[5];
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
24.11.2015, 08:55
Привет! Вот еще темы с ответами:

Почему адреса одинаковые? - C++
Обьясните пожалуйста код, почему адреса одинаковые? #include &lt;iostream&gt; using namespace std; int main() { char *s =...

Почему выводит адреса? - C++
Всем привет! Программа работает, но почему то выводит данные вместе с адресом (см. скриншот). Скажите, почему так? #include&lt;iostream&gt; ...

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

Почему в scanf нужно указывать именно адреса переменных? - C++
Почему в функции scanf нужно указывать именно адреса переменных? Почему не работает, когда указываем переменную? Что хранит в себе...


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

Или воспользуйтесь поиском по форуму:
30
Yandex
Объявления
24.11.2015, 08:55
Ответ Создать тему
Опции темы

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