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

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 27, средняя оценка - 4.63
Hagrael
БТР - мой друг
331 / 273 / 2
Регистрация: 07.01.2010
Сообщений: 1,932
#1

Указатели - C++

23.06.2011, 20:08. Просмотров 3432. Ответов 54
Метки нет (Все метки)

1) Указатель можно инициализирвоать только с помощью операции *p=&a? А как записать адрес переменной в простую переменную (я пытался это делать через операцию b=&a, но компилятор ругается, говорит, что операция &a возвращает указатель.
2) Почему имеет значение тип указателя? Ведь это просто ссылка на переменную.

И еще один вопрос, не касающийся указателей:
3) Как программа узнает, какие места ОЗУ ей можно занимать (не заняты др. программой), а какие - нет.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
23.06.2011, 20:08
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Указатели (C++):

Указатели и указатели на указатели, а также типы данных - 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;// выделил для первой строки матрицы два...

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

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

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
sandye51
программист С++
682 / 584 / 39
Регистрация: 19.12.2010
Сообщений: 2,016
23.06.2011, 20:12 #2
Цитата Сообщение от Hagrael Посмотреть сообщение
1) Указатель можно инициализирвоать только с помощью операции
нет. Варианты
C++
1
2
3
4
int a = 4;
int* p1 = &a;
int* p2 = p1;
int* p3 = new int[size];
Цитата Сообщение от Hagrael Посмотреть сообщение
Ведь это просто ссылка на переменную.
нет. Это ее адрес.

Цитата Сообщение от Hagrael Посмотреть сообщение
Как программа узнает, какие места ОЗУ ей можно занимать (не заняты др. программой), а какие - нет.
читай про структуру ВАП и управление памятью в ОС
OstapBender
583 / 521 / 35
Регистрация: 22.03.2011
Сообщений: 1,585
23.06.2011, 20:19 #3
важно также, что не *p=&a,
а p=&a;

если не при объявлении конечно
Kastaneda
Форумчанин
Эксперт С++
4518 / 2860 / 228
Регистрация: 12.12.2009
Сообщений: 7,268
Записей в блоге: 2
Завершенные тесты: 1
23.06.2011, 20:20 #4
Цитата Сообщение от sandye51 Посмотреть сообщение
нет. Варианты...
и даже так:
int *p=(int*)123456;


Цитата Сообщение от Hagrael Посмотреть сообщение
Почему имеет значение тип указателя?
А как компилятор узнает, сколько байт по этому адресу ему нужно использовать (прочитать/записать)? Плюс арифметика указателей:
C++
1
2
int *ptr;
++ptr;//указатель увеличился на sizeof(int), а не на 1
silent_1991
Эксперт С++
4963 / 3039 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
23.06.2011, 20:21 #5
OstapBender, а при объявлении звёздочка относится к типу, а не к переменной, так что всё равно p = &a;
OstapBender
583 / 521 / 35
Регистрация: 22.03.2011
Сообщений: 1,585
23.06.2011, 20:27 #6
silent_1991, да я понял, что про объявление не совсем точно написал. ну все равно чисто визуально может показаться что пишется *p = ... =)
Nameless One
Эксперт С++
5771 / 3420 / 255
Регистрация: 08.02.2010
Сообщений: 7,447
24.06.2011, 06:50 #7
Цитата Сообщение от Hagrael Посмотреть сообщение
А как записать адрес переменной в простую переменную (я пытался это делать через операцию b=&a, но компилятор ругается, говорит, что операция &a возвращает указатель.
Можно сделать так:
C
1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
#include <stdlib.h>
 
int main()
{
    int x, address_of_x, *pointer_to_x;
    x = 3;
    address_of_x = (int) &x;
    pointer_to_x = (int*) address_of_x;
    printf("memory address of x = %p, x = %d\n", pointer_to_x, *pointer_to_x);
    exit(0);
}
Или даже так:
C
1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
#include <stdlib.h>
 
int main()
{
    int x, address_of_x;
    x = 3;
    address_of_x = (int) &x;
    printf("memory address of x = %p, x = %d\n", (int*) address_of_x, *(int*) address_of_x);
    exit(0);
}
Но наверно понятно, что так делать не надо. Зачем хранить адрес переменной в простой переменной, если для этого существуют указатели?
Hagrael
БТР - мой друг
331 / 273 / 2
Регистрация: 07.01.2010
Сообщений: 1,932
24.06.2011, 11:20  [ТС] #8
Цитата Сообщение от sandye51 Посмотреть сообщение
нет. Варианты ...
Спасибо за различные способы, но последний я не до конца понял. Там, что, int используется как класс? И что означает size? Буду признателен, если вы объясните.

Цитата Сообщение от sandye51 Посмотреть сообщение
Ведь это просто ссылка на переменную.
нет. Это ее адрес.
Я, кажется, понял! Операция &a возвращает указатель, однако указатель можно преобразовать в простой тип int! Почему именно указатель, а не простой тип (который можно было бы преобразовать в указатель)? Потому, что гораздо чаще с этой операции нужно получить указатель, чем сам адрес, и потому для быстроты разработчики решили, что операция &a должна возвращать указатель. Все верно?

Цитата Сообщение от sandye51 Посмотреть сообщение
читай про структуру ВАП и управление памятью в ОС
ОК.

Цитата Сообщение от Kastaneda Посмотреть сообщение
int *p=(int*)123456;
А вот это интересно! Тогда, выходит, ты сам задаешь адрес для указателя? И если так, то такой код:
C++
1
2
int* p=(int*) 123;
cout << *p;
выдает ошибку "Память не может быть reed", поскольку это запретный для моей программы узел?

Цитата Сообщение от Nameless One Посмотреть сообщение
address_of_x = (int) &x;
И снова еще один способ преобразовать тип переменной! Да сколько их там вообще?))
C++
1
2
3
b=static_cast<int>(a);
b=int(a);
b=(int) a;
Они все чем-то отличаются или нет?

Цитата Сообщение от Kastaneda Посмотреть сообщение
А как компилятор узнает, сколько байт по этому адресу ему нужно использовать (прочитать/записать)?
Хм. Теперь у меня возник такой вопрос: Как вообще программа узнает, сколько байт имеет та или иная переменная? Вот к примеру код:
C++
1
2
int a;
a=5.5;
Вот откуда программа узнает, что надо отбросить дробную часть? В самой переменной a ведь не хранится ее размер. По-моему, тип уже лежит в коде, и программе не надо узнавать его. То есть когда ты говоришь int a;, компилятор запоминает, что переменная a в данном скопе имеет тип int и в последствии в откомпилированном коде что-то меняется. То есть в коде не сказано
Код
Присвоить переменной a значение 5.5
а написано
Код
Присвоить переменной а значение 5.5 без дробной части
Я правильно понимаю?
pito211
186 / 173 / 8
Регистрация: 22.03.2010
Сообщений: 612
24.06.2011, 11:46 #9
Вот откуда программа узнает, что надо отбросить дробную часть?
в данном случае на этапе компиляции:
Assembler
1
2
3
int a;
a = 5.5;
010114B7  mov         dword ptr [a],5
Hagrael
БТР - мой друг
331 / 273 / 2
Регистрация: 07.01.2010
Сообщений: 1,932
24.06.2011, 11:48  [ТС] #10
Цитата Сообщение от pito211 Посмотреть сообщение
в данном случае на этапе компиляции
А разве может быть по-другому?
pito211
186 / 173 / 8
Регистрация: 22.03.2010
Сообщений: 612
24.06.2011, 11:55 #11
конечно.
Assembler
1
2
3
4
5
6
7
8
9
10
int a;
a = 5.5;
00D714F7  mov         dword ptr [a],5 
double f = 5.5;
00D714FE  fld         qword ptr [__real@4016000000000000 (0D75920h)] 
00D71504  fstp        qword ptr [f] 
a = f;
00D71507  fld         qword ptr [f] 
00D7150A  call        @ILT+220(__ftol2_sse) (0D710E1h) 
00D7150F  mov         dword ptr [a],eax
Добавлено через 2 минуты
Цитата Сообщение от Hagrael Посмотреть сообщение
Операция & возвращает указатель
адресс
Nameless One
Эксперт С++
5771 / 3420 / 255
Регистрация: 08.02.2010
Сообщений: 7,447
24.06.2011, 12:03 #12
Цитата Сообщение от Hagrael Посмотреть сообщение
Спасибо за различные способы, но последний я не до конца понял. Там, что, int используется как класс? И что означает size? Буду признателен, если вы объясните.
это означает выделение динамическое выделение памяти под массив размером size
Я, кажется, понял! Операция &a возвращает указатель, однако указатель можно преобразовать в простой тип int! Почему именно указатель, а не простой тип (который можно было бы преобразовать в указатель)? Потому, что гораздо чаще с этой операции нужно получить указатель, чем сам адрес, и потому для быстроты разработчики решили, что операция &a должна возвращать указатель. Все верно?
Не совсем. Указатель на переменную не просто хранит беззнаковое целое число (если бы это было не так, то везде можно было бы использовать вместо указателей переменные типа size_t), но он еще и знает о размере типа, на переменную которого он указывает. Это необходимо при разыменовании и арифметике указателей (т.е. инкременте или декременте). Например:
C
1
2
3
4
5
6
7
double d, *pd;
int i, *pi;
char p, *pc;
pi = &i, pd = &d;
++pi; // адрес i + sizeof(int)
++pd; // адрес d + sizeof(double)
++pc; // адрес с + sizeof(char)
Как видно, при инкременте указателей разных типов переход по памяти происходит именно на размер данного типа. В этом легко убедиться, если распечатать значения указателей
А вот это интересно! Тогда, выходит, ты сам задаешь адрес для указателя? И если так, то такой код:
C++
1
2
int* p=(int*) 123;
cout << *p;
выдает ошибку "Память не может быть reed", поскольку это запретный для моей программы узел?
Так делать нельзя. Память в программе должна быть либо выделена статически, либо динамически. Ты же взял произвольный адрес (невыделенной памяти), и попытался его разыменовать (т.е. вывести значение переменной типа int, находящееся по адресу 123), и, естественно, это приводит к ошибке.
И снова еще один способ преобразовать тип переменной! Да сколько их там вообще?))
C++
1
2
3
b=static_cast<int>(a);
b=int(a);
b=(int) a;
Они все чем-то отличаются или нет?
первая строка - явное приведение типов в стиле С++, вторая - инициализация переменной b, третья - явное приведение типов в стиле С
Хм. Теперь у меня возник такой вопрос: Как вообще программа узнает, сколько байт имеет та или иная переменная? Вот к примеру код:
C++
1
2
int a;
a=5.5;
Вот откуда программа узнает, что надо отбросить дробную часть?
Тут происходит неявное приведение типов
В самой переменной a ведь не хранится ее размер.
Тип и размер ВСЕХ переменных известен на уже этапе компиляции
По-моему, тип уже лежит в коде, и программе не надо узнавать его. То есть когда ты говоришь int a;, компилятор запоминает, что переменная a в данном скопе имеет тип int и в последствии в откомпилированном коде что-то меняется.
Поздравляю, ты открыл статическую типизацию
То есть в коде не сказано
Код
Присвоить переменной a значение 5.5
а написано
Код
Присвоить переменной а значение 5.5 без дробной части
Я правильно понимаю?
Нет, в коде сказано: у нас есть значение типа double, а переменная типа int. Несоответствие. Надо выполнить приведение типов (а при этом как раз происходит отбрасывание дробной части)
Hagrael
БТР - мой друг
331 / 273 / 2
Регистрация: 07.01.2010
Сообщений: 1,932
24.06.2011, 12:04  [ТС] #13
Цитата Сообщение от pito211 Посмотреть сообщение
Операция & возвращает указатель

адресс
Но она же возвращает переменную с типом type*. А такие переменные называются указателями. Чем является адрес?
Nameless One
Эксперт С++
5771 / 3420 / 255
Регистрация: 08.02.2010
Сообщений: 7,447
24.06.2011, 12:07 #14
Цитата Сообщение от Hagrael Посмотреть сообщение
Чем является адрес
Адрес он и в африке адрес. Натуральное число, являющееся адресом в памяти, по которому расположена переменная типа type.
pito211
186 / 173 / 8
Регистрация: 22.03.2010
Сообщений: 612
24.06.2011, 12:14 #15
Цитата Сообщение от Hagrael Посмотреть сообщение
Но она же возвращает переменную с типом type*
возвращает она адрес, а указатель это переменная содержащая адрес
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
24.06.2011, 12:14
Привет! Вот еще темы с ответами:

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

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

Указатели на массивы. Указатели и функции - C++
Вот задача: Даны два массива : А и B. Необходимо создать третий массив, в котором нужно собрать: -Элементы обоих массивов; -Общие...

Константные указатели и указатели на константу - C++
Чем они, собственно говоря, отличаются? Поясните, пожалуйста. Не знаю, как так получилось, что в разных источниках - разные...


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

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

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