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

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

Войти
Регистрация
Восстановить пароль
 
 
extremist38
0 / 0 / 0
Регистрация: 19.12.2012
Сообщений: 6
#1

Указатели. Не понимаю - C++

19.12.2012, 03:27. Просмотров 670. Ответов 18
Метки нет (Все метки)

Разбираю указатели, слегка запнулся на одном месте.

У меня есть функция:
C++
1
2
3
4
void Dit(int &x)
{
    x *= 2;
}
Использую я в программе это так:
C++
1
Dit(x);
И я не могу понять, почему это работает.
Судя по книжке, которую я читаю, & - взятие адреса. То есть получается, я передаю в функцию адрес. А внутри её использую как обычную переменную. При попытке написать что-то в стиле "*x *= 2;" компилятор пишет, что неверно. Почему так?

Добавлено через 20 минут
Также есть небольшая ситуация.
Возможно использования массивов через указатели, то есть.

C++
1
2
3
int *p;
int arr[100500];
p = &arr;
При этом, если делать p++, то говорится, что р будет указывать на следующий элемент в массиве. Но ведь элементы массива в оперативной памяти разбросаны по участкам и не обязательно идут друг за дружкой (особенно если массив весит очень много). Насколько я знаю, p++ к указателю даёт результат следующей ячейки в памяти. И у меня возникает вопрос: кто следит за тем, чтобы p указывал именно на следующий элемент в массиве, а не в памяти? И гарантированно ли он будет указывать?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
19.12.2012, 03:27
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Указатели. Не понимаю (C++):

не совсем понимаю код *указатели - C++
изучаю указатели, столкнулся с кодом не совсем могу понять что происходит в функции *g_s, особенно это условие *p2 && *p2 == *p ...

Правильно ли я понимаю ссылки и указатели. Работу с ними. Я сам прокомментировал код. Скажите правильно или нет. - C++
#pragma once namespace Casper { class Cat { private: unsigned int age; float weight;

Указатели и указатели на указатели, а также типы данных - C++
Недавно начал изучать Си, перешел с Delphi. Много непонятного и пока процесс идет медленно. Накачал литературы, буду изучать) Щас...

Через указатели на указатели посчитать сумму двух чисел и записать в третье - C++
1. Через указатели на указатели посчитать сумму двух чисел и записать в третье. 2. Написать примитивный калькулятор, пользуясь только...

Есть три переменные. Используя указатели на указатели, поменять значение максимальной и минимальной переменной - C++
Мой код. #include <iostream> #include <stdlib.h> #include<iomanip> using namespace std; void min_max(int*pa, int*pb,...

Указатели на указатели с числами. Почему можно присвоить число в 4-ый элемент, если массив из 2 элементов? - C++
Есть массив int **mas; mas=new int*; // выделил место под пять строк, верно ? mas=new int;// выделил для первой строки матрицы два...

18
icecreeam
3 / 3 / 0
Регистрация: 25.06.2012
Сообщений: 13
19.12.2012, 03:35 #2
Цитата Сообщение от extremist38 Посмотреть сообщение
И я не могу понять, почему это работает.
Судя по книжке, которую я читаю, & - взятие адреса. То есть получается, я передаю в функцию адрес. А внутри её использую как обычную переменную. При попытке написать что-то в стиле "*x *= 2;" компилятор пишет, что неверно. Почему так?
на сколько я знаю, знак амперсанда используется не только для взятия адреса, а и для работы с ссылочными типами данных.

По поводу массивов мне кажется что его элементы не разбросаны и идут друг за другом.
0
extremist38
0 / 0 / 0
Регистрация: 19.12.2012
Сообщений: 6
19.12.2012, 03:46  [ТС] #3
Цитата Сообщение от icecreeam Посмотреть сообщение
на сколько я знаю, знак амперсанда используется не только для взятия адреса, а и для работы с ссылочными типами данных.
Тогда что означает то, что я написал?
0
0x10
2544 / 1724 / 260
Регистрация: 24.11.2012
Сообщений: 4,337
19.12.2012, 03:48 #4
Цитата Сообщение от extremist38 Посмотреть сообщение
void Dit(int &x)
Функция, принимающая целочисленный аргумент по ссылке.

Добавлено через 41 секунду
Цитата Сообщение от extremist38 Посмотреть сообщение
p = &arr;
Взятие адреса указателя на нулевой элемент массива.
0
extremist38
0 / 0 / 0
Регистрация: 19.12.2012
Сообщений: 6
19.12.2012, 03:51  [ТС] #5
Цитата Сообщение от 0x10 Посмотреть сообщение
Функция, принимающая целочисленный аргумент по ссылке.
То есть получается, что я не ссылку принимаю? Или всё же ссылку?
0
icecreeam
3 / 3 / 0
Регистрация: 25.06.2012
Сообщений: 13
19.12.2012, 03:54 #6
C++
1
void Dit(int &x)
в этом случае вы передаете значение по ссылке
C++
1
Dit(x)
при вызове

C++
1
void Dit(int *x)
а в этом вы передаете адрес значения
C++
1
Dit(&x)
при вызове

описал на сколько я себе это представляю.
1
extremist38
0 / 0 / 0
Регистрация: 19.12.2012
Сообщений: 6
19.12.2012, 04:09  [ТС] #7
Кликните здесь для просмотра всего текста
Цитата Сообщение от icecreeam Посмотреть сообщение
C++
1
void Dit(int &x)
в этом случае вы передаете значение по ссылке
C++
1
Dit(x)
при вызове

C++
1
void Dit(int *x)
а в этом вы передаете адрес значения
C++
1
Dit(&x)
при вызове

описал на сколько я себе это представляю.

Я прекрасно понимаю, как работает второй вариант. Только с первым непонятки. Если я передаю значение, почему тогда переменная изменяется? Или я передаю значение вместе с ссылкой? (то есть саму переменную??...)

Добавлено через 2 минуты
Цитата Сообщение от 0x10 Посмотреть сообщение
Функция, принимающая целочисленный аргумент по ссылке.

Добавлено через 41 секунду

Взятие адреса указателя на нулевой элемент массива.
Всё же, всегда ли элементы массива идут друг за дружкой? Что происходит, если невозможно выделить массив одним куском?
0
0x10
2544 / 1724 / 260
Регистрация: 24.11.2012
Сообщений: 4,337
19.12.2012, 04:14 #8
Цитата Сообщение от extremist38 Посмотреть сообщение
Я прекрасно понимаю, как работает второй вариант. Только с первым непонятки. Если я передаю значение, почему тогда переменная изменяется? Или я передаю значение вместе с ссылкой? (то есть саму переменную??...)
Создается ссылка, которая инициализируется объектом.

Цитата Сообщение от extremist38 Посмотреть сообщение
Всё же, всегда ли элементы массива идут друг за дружкой?
А как иначе-то?

Цитата Сообщение от extremist38 Посмотреть сообщение
Что происходит, если невозможно выделить массив одним куском?
Предполагаю, что происходит пичалька. (объяснил, да? =) )
2
extremist38
0 / 0 / 0
Регистрация: 19.12.2012
Сообщений: 6
19.12.2012, 04:17  [ТС] #9
Цитата Сообщение от 0x10 Посмотреть сообщение
Предполагаю, что происходит пичалька. (объяснил, да? =) )
Понятно, что примерно выходит )
Следующий вопрос будет: как можно предусмотреть такую ситуацию и предотвратить печальку? )
0
OhMyGodSoLong
~ Эврика! ~
1244 / 993 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
19.12.2012, 04:22 #10
Цитата Сообщение от extremist38 Посмотреть сообщение
Всё же, всегда ли элементы массива идут друг за дружкой? Что происходит, если невозможно выделить массив одним куском?
1. Всегда.

2. Память не выделяется. А дальше в зависимости от настроек и т. п. возможны три варианта:
a) есть вариант new с дополнительным аргументом, который заставит new просто вернуть NULL;
б) по умолчанию new выбрасывает исключение std::bad_alloc;
в) с помощью set_new_handler() можно установить функцию-обработчик на этот случай, которая должна или повыбрасывать всякий мусор, чтобы new попробовала выделить память ещё раз, или выбросить std::bad_alloc или прибить программу, если она облажалась с высвобождением.
1
ValeryS
Модератор
6918 / 5261 / 512
Регистрация: 14.02.2011
Сообщений: 17,691
19.12.2012, 07:25 #11
Цитата Сообщение от extremist38 Посмотреть сообщение
int *p;
int arr[100500];
p = &arr;
ошибка будет
вот такая
1> error C2440: =: невозможно преобразовать 'int (*)[100500]' в 'int *'
все дело в том что arr уже имеет тип int * (указатель)
нет в С массивов как например в Фортране
есть указатель на область памяти где лежит массив
а этим
C++
1
p = &arr
ты берешь указатель на указатель
значит надо писать так если тебе нужна копия указателя
C++
1
2
3
int *p;
int arr[100500];
p = arr;
или так
C++
1
2
3
int *p;
int arr[100500];
p = &arr[0];
что означает взять указатель на первый(нулевой) элемент массива arr
и это равнозначно p = arr
0
OhMyGodSoLong
19.12.2012, 09:16
  #12

Не по теме:

Цитата Сообщение от ValeryS Посмотреть сообщение
нет в С массивов как например в Фортране
Но схитрить можно:
struct array { int data[100500]; };
Такая штука позволяет передавать массивы по значению.

0
taras atavin
3887 / 1761 / 92
Регистрация: 24.11.2009
Сообщений: 27,566
19.12.2012, 09:55 #13
extremist38, указатель есть данное, хранящее адрес подпрограммы, или другого данного. Кратный указатель есть данное, хранящее адрес другого указателя. Указатель, хранящий адрес указателя, хранящего адрес не указателя, называется двойным указателем, указатель, хранящий адрес указателя, хранящего адрес указателя, хранящего адрес указателя, называется тройным указателем и так далее. Сколько указателей нужно использовать, чтоб добраться до не указателя, такова и кратность указателя. Адрес есть значение самого указателя. Адрес есть номер байта в памяти, с которого начинается то, чей это адрес. Например, адрес переменной есть номер байта в памяти, с которого начинается эта переменная. Ссылка есть синоним другой переменной. Можно считать, что ссылка ведёт себя, как неявно разыменуемый при каждом обращении к нему указатель. Но стандарт не гарантирует реализацию ссылок через указатели, вместо этого ссылка может быть реализована дублированием адреса в таблице переменных компилятора, а в готовом коде будет прямая адресация, то есть доступ по адресу в коде программы, а не в данном. Исключение - передаваемые по ссылкам параметры неинлайновых функций и передаваемые по ссылкам операнды неинлайновых перегруженных операторов, в этом случае альтернативные реализации не возможны и ссылка становится синтаксической надстройкой над указателем. Разыменование указателя есть операция доступа не к самому указателю, а к тому, чей адрес он хранит, на низком уровне разыменованию соответствует операция косвенной адресации.

Добавлено через 2 минуты
Цитата Сообщение от ValeryS Посмотреть сообщение
нет в С массивов как например в Фортране
C
1
char s[16];
- массив.

Добавлено через 1 минуту
Цитата Сообщение от extremist38 Посмотреть сообщение
& - взятие адреса.
Нет. У тебя этот оператор стоит в декларации, а в этом случае & означает, что следующий идентификатор есть имя ссылки.

Добавлено через 3 минуты
Цитата Сообщение от extremist38 Посмотреть сообщение
Но ведь элементы массива в оперативной памяти разбросаны по участкам и не обязательно идут друг за дружкой
Они не разбрасываются, классический массив - это единый блок, не путай его с массивами-объектами, которые могут быть реализованы на чём угодно, включая списки. Но тогда каждый элемент будет хранить адрес следующего, а оператор ++ для указателя перегружается на копирование адреса следующего элемента из текущего.

Добавлено через 4 минуты
Цитата Сообщение от ValeryS Посмотреть сообщение
нет в С массивов как например в Фортране
есть указатель на область памяти где лежит массив
Массивы в c/c++ есть, просто они реализованы на указателях. Но
C++
1
2
3
4
5
6
7
int a[1000];
int *p=a;
std::cout<<sizeof(a); // выведет размер тысячи интов, а не указателя
std::cout<<std::endl;
std::cout<<sizeof(p);// выведет размер самого указателя
std::cout<<std::endl;
std::cout<<sizeof(a[0]);// выведет размер нулевого элемента
, в то же время
C++
1
2
int a[1000];
int *p=a; // здесь a - указатель и присвоено будет значение указателя указателю же
.
1
extremist38
0 / 0 / 0
Регистрация: 19.12.2012
Сообщений: 6
19.12.2012, 10:30  [ТС] #14
Цитата Сообщение от taras atavin Посмотреть сообщение
Но стандарт не гарантирует реализацию ссылок через указатели, вместо этого ссылка может быть реализована дублированием адреса в таблице переменных компилятора, а в готовом коде будет прямая адресация, то есть доступ по адресу в коде программы, а не в данном. Исключение - передаваемые по ссылкам параметры неинлайновых функций и передаваемые по ссылкам операнды неинлайновых перегруженных операторов, в этом случае альтернативные реализации не возможны и ссылка становится синтаксической надстройкой над указателем. Разыменование указателя есть операция доступа не к самому указателю, а к тому, чей адрес он хранит, на низком уровне разыменованию соответствует операция косвенной адресации.
Спасибо за объяснение. Тогда такой вопрос:
Будет ли реализация через ссылку
C++
1
2
3
4
void Dit(int &x)
{
    x *= 2;
}
являться грамотно написанной и работающей? Или это всё же лучше делать через указатели?
0
Croessmah
Ушел
Эксперт CЭксперт С++
13713 / 7963 / 909
Регистрация: 27.09.2012
Сообщений: 19,602
Записей в блоге: 3
Завершенные тесты: 1
19.12.2012, 10:32 #15
Цитата Сообщение от extremist38 Посмотреть сообщение
являться правильно написанной и гарантированно работающей? Или это всё же лучше делать через указатели?
Для этого их и придумали - чтобы не возится с указателями, как в Си, да и код выглядит понятнее
0
19.12.2012, 10:32
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.12.2012, 10:32
Привет! Вот еще темы с ответами:

Отсортировать массив и вывести на экран (массивы и указатели на указатели) - C++
Даны массивы F-фамилий студентов и S-результаты сессии (5 оценок) , причем s- результат сессии F студента. Отсортировать массив S по...

Написать программу сортировки через указатели на указатели - C++
Вот моя программа #include &lt;iostream&gt; #include &lt;conio.h&gt; #include &lt;string&gt; using namespace std; //Сортировка &quot;пузырьком&quot;. ...

Указатели на слонов или А зачем нужны указатели? - C++
Знаю что таких вопросов было уйма, но я так и не нашел ответа на свой вопрос. Для чего нужны указатели? Что такое указатели я знаю, это...

Используются ли на практике указатели на указатели объектов? - C++
Имеются ввиду указатели именно на объекты, а не динамические массивы. Например такой: Object** obj; А как насчёт такого: Object***...


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

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

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