C++ указатели вопрос по ним. (Вопрос начинаюшего.)

Софт под Linux, разные программы, но только связанные с Linux

Модератор: /dev/random

Slimy
Сообщения: 1689
ОС: openSuSE 11.2 GM (GеMор едишн)

C++ указатели вопрос по ним.

Сообщение Slimy »

В общем имеется сырец.

#include <iostream>
using namespace std;
int main()
{
int a=2;
int *p=&a;
cout << "*p=" << p << endl; // *p=2
*p=5;
cout << "a=" << a << endl;
return 0;
}

в общем разъяните новичку роль * и & в частности строку int *p=&a
если p содержит адресс по почему он целогого типа и зачем ему указывать * если констукция &a возращает адресс а р сам по себе соджержит адресс ? Пример я взял из книги, но в ней так написано что ничгео не понтяно почему именон так записывается.
Если уже ничего не помогает - прочти инструкцию.
sysinstall - гадость :)
ASUS A6q00Vm Pentium-M 1.7 GHz, 2Gb RAM, 160Gb HDD,
GeForce Go 7300 64Mb video
Спасибо сказали:
Аватара пользователя
Alxn1
Сообщения: 402
Статус: Красноглазик со стажем
ОС: Mavericks

Re: C++ указатели вопрос по ним.

Сообщение Alxn1 »

Ммм... Вам бы почитать что-нибудь, тем более, что пример из книги вы взяли. Там должно бы быть написано. Особенно про такие вещи, как указатели и тем более типизированные. int* - это обьявление указателя на переменные типа int. Т.е. предполагается, что данная переменная будет содержать адрес области памяти, в которой хранится одна или несколько переменных типа int. Аналогично могут существовать переменные типов float*, double*, long* и прочее. И даже указатели на указаели: int**. Стоит отметить, что при обьявлении переменных есть некоторый казус: int *a,b; - в данном случае переменая a будет указателем, а b - просто переменной типа int. Потому обычно * пишут впритык к имени переменной, а не к типу.

Для того, что бы узнать адрес некоторой переменной, используется оператор &. Например, если есть переменная int a и указатель int *pa, то записать адрес переменной a в pa можно так: pa=&a;. Или сразу при обьявлении переменной-указателя: int *pa=&a;

После того, как указатель содержит адрес некоторой переменной, к той переменной можно обращаться по адресу, что записан в указателе, с помощью всё той же *. Нпример:

Код: Выделить всё

       float a=10;
       float *pa=&a;

      *pa=100; //   Тут происходит обращение к переменной а по её адресу, содержащемуся в pa.
                     // Переменная a принимает значение 100.


Дальнейшее введение в язык С прошу проходить по книге/гам. :) Удачи. :)
Спасибо сказали:
azat.h
Сообщения: 45

Re: C++ указатели вопрос по ним.

Сообщение azat.h »

Это подробно описанно у Кернигана и Ричи (например http://www.lib.ru/CTOTOR/kernigan.txt )
IMHO Изучение С++ лучше начинать с простого С (без плюсов). А использование указателей в С/C++ это довольно сложный вопрос, иногда на одну и ту же конструкцию разные версии gcc реагируют по разному.
Спасибо сказали:
Аватара пользователя
Alxn1
Сообщения: 402
Статус: Красноглазик со стажем
ОС: Mavericks

Re: C++ указатели вопрос по ним.

Сообщение Alxn1 »

azat.h писал(а):
27.09.2006 02:40
Это подробно описанно у Кернигана и Ричи (например http://www.lib.ru/CTOTOR/kernigan.txt )


Согласен, книга будет полезной.

azat.h писал(а):
27.09.2006 02:40
IMHO Изучение С++ лучше начинать с простого С (без плюсов).


Не факт, многие, как недавно узнал, педагоги-теоретики ведут споры по этому поводу. :D А по мне, так с С++. С++ почти полностью вкдючает С в себя, как подмножество, т.е. начав изучение с С++ ничего не теряешь. А вот если начать с С, то потом некоторые вещи (приведение типов, например, особенно указателей, структуры) придётся переучивать. Да и ООП, всё-таки... IMHO, конечно.

azat.h писал(а):
27.09.2006 02:40
А использование указателей в С/C++ это довольно сложный вопрос, иногда на одну и ту же конструкцию разные версии gcc реагируют по разному.


Ммм... Если только приведение типов может хромать, однако если писать по стандарту, граблей быть не должно, IMHO. Вот шаблоны - это да. Костыль на костыле. То работает, то нет... Ужас просто :D
Спасибо сказали:
azat.h
Сообщения: 45

Re: C++ указатели вопрос по ним.

Сообщение azat.h »

Alxn1 писал(а):
27.09.2006 02:47
Не факт, многие, как недавно узнал, педагоги-теоретики ведут споры по этому поводу. :D А по мне, так с С++. С++ почти полностью вкдючает С в себя, как подмножество, т.е. начав изучение с С++ ничего не теряешь. А вот если начать с С, то потом некоторые вещи (приведение типов, например, особенно указателей, структуры) придётся переучивать. Да и ООП, всё-таки... IMHO, конечно.

Ну на то они и "теоретики", у них работа такая ;-)

Alxn1 писал(а):
27.09.2006 02:47
Ммм... Если только приведение типов может хромать, однако если писать по стандарту, граблей быть не должно, IMHO. Вот шаблоны - это да. Костыль на костыле. То работает, то нет... Ужас просто :D

Сам так думал, пока не столкнулся с http://www.gnu.org/software/radius/
При компиляции gcc 4.1.2 начал выдавать ошибки. Файл radius-1.3/radiusd/log.c , строка 200 До этого, я надеюсь, он собирался. Возможно и с предупреждениями. Ругался на 200 строку.

Код: Выделить всё

static void
channel_format_prefix(struct logbuf *bufp,
                      Channel *chan, const grad_request_t *req)
{
        char **hook_name_ptr = &(chan->prefix_hook ?
                                   chan->prefix_hook : log_prefix_hook); /* ругался на эту строку

после замены на

Код: Выделить всё

        char **hook_name_ptr = (chan->prefix_hook ?
                                   &chan->prefix_hook : &log_prefix_hook);

он по крайней мере компилируется. ;-) Код не мой, кто нарушил стандарт не знаю, мне просто нужен был альтернативный радиус-сервер.
А на счет приведения типов это отдельная песня! У меня тестовая машина PPC G4 и некоторые проги показывают просто чудеса ;-) Хотя при этом нормально компилируются.
P.S. это относится не к прогам из дистрибутивов, к ним претензий нет (почти), а к местному "народному творчеству".
Спасибо сказали:
wRAR
Сообщения: 372
ОС: ALT Linux Sisyphus

Re: C++ указатели вопрос по ним.

Сообщение wRAR »

( ? : ) не является lvalue, и адрес его брать нельзя. В старых версиях gcc было по-другому. Только вот этот пример к указателям отношения не имеет, точно так же сломался бы код

Код: Выделить всё

(a > b ? a : b) = 0;
ALT Linux Team
SIM-IM Development Team
Antilamer
Спасибо сказали:
azat.h
Сообщения: 45

Re: C++ указатели вопрос по ним.

Сообщение azat.h »

Спасибо!
Про

Код: Выделить всё

(a > b ? a : b) = 0;
знал, но не думал, что это из-за этого. Просто исправил код.
Спасибо сказали:
Slimy
Сообщения: 1689
ОС: openSuSE 11.2 GM (GеMор едишн)

Re: C++ указатели вопрос по ним.

Сообщение Slimy »

Alxn1 писал(а):
27.09.2006 02:26
Ммм... Вам бы почитать что-нибудь, тем более, что пример из книги вы взяли. Там должно бы быть написано. Особенно про такие вещи, как указатели и тем более типизированные. int* - это обьявление указателя на переменные типа int. Т.е. предполагается, что данная переменная будет содержать адрес области памяти, в которой хранится одна или несколько переменных типа int. Аналогично могут существовать переменные типов float*, double*, long* и прочее. И даже указатели на указаели: int**. Стоит отметить, что при обьявлении переменных есть некоторый казус: int *a,b; - в данном случае переменая a будет указателем, а b - просто переменной типа int. Потому обычно * пишут впритык к имени переменной, а не к типу.

Для того, что бы узнать адрес некоторой переменной, используется оператор &. Например, если есть переменная int a и указатель int *pa, то записать адрес переменной a в pa можно так: pa=&a;. Или сразу при обьявлении переменной-указателя: int *pa=&a;

После того, как указатель содержит адрес некоторой переменной, к той переменной можно обращаться по адресу, что записан в указателе, с помощью всё той же *. Нпример:

Код: Выделить всё

       float a=10;
       float *pa=&a;

      *pa=100; //   Тут происходит обращение к переменной а по её адресу, содержащемуся в pa.
                     // Переменная a принимает значение 100.


Дальнейшее введение в язык С прошу проходить по книге/гам. :) Удачи. :)

Спасибо за ответ. Я вот и хожу по книгам. Просто именон этот момент для меня остался не понятным несмотря на его прочтение. В описании исходника написано что присвоение указателю адреса просходит через p=&a(что у меня не вызывало вопросо т.к. вполне логично), а уже в самой програмее появилось * хотя до этого говорится что * возращает значение по адрессу указанному в p т.е. если с таким представлением прочитать строку *p=&a то выходит что адрес ячейки, a присваивается ввиде значения в ячейку на которую указывает адрес в p т.к. написано с оператором *. Вот это меня и запутало.
Из вашего же объяснения следует что это всего лишь ее объявление. Но если так она объявляется то тогда какая разница между объявлением и использованием значения ведь запись будет одинаковая? *p :unsure:
к томуже тип переменной адрес которой хранится в р уже задан при ее объявлении зачем тогда объявлять его еще раз? или возможен вариант что переменная int может быть прочитана как допустим float если использовать указатель ? (такой вырутас сильно на ассемблер похож).
В общем книги (доступные мне ) ответа на эти вопросы не дают. А с указательми с этими разобратся нужно иначе дальше изучать C++ невозможно т.к. указатели эти в каждой функции подчти встречаются а при работе с объектами так 100% наличествуют.
P.S. Я тему создавал уже позно было и промахнулся немного между программами и программированием. Хотелось бы чтобы модераторы перенесли ее в соответсвующий раздел.
Если уже ничего не помогает - прочти инструкцию.
sysinstall - гадость :)
ASUS A6q00Vm Pentium-M 1.7 GHz, 2Gb RAM, 160Gb HDD,
GeForce Go 7300 64Mb video
Спасибо сказали:
wRAR
Сообщения: 372
ОС: ALT Linux Sisyphus

Re: C++ указатели вопрос по ним.

Сообщение wRAR »

(Slimy @ Sep 27 2006, в 16:21) писал(а):Но если так она объявляется то тогда какая разница между объявлением и использованием значения ведь запись будет одинаковая? *p

Да нет же. Здесь звездочка относится к типу.
(Slimy @ Sep 27 2006, в 16:21) писал(а):к томуже тип переменной адрес которой хранится в р уже задан при ее объявлении зачем тогда объявлять его еще раз?

Вы объявляете p ровно один раз. А что вы там ему присваиваете - дело десятое. Без указания типа вы переменную не объявите.
(Slimy @ Sep 27 2006, в 16:21) писал(а):или возможен вариант что переменная int может быть прочитана как допустим float если использовать указатель ?

При работе с классами такое используется сплошь и рядом.
ALT Linux Team
SIM-IM Development Team
Antilamer
Спасибо сказали:
Slimy
Сообщения: 1689
ОС: openSuSE 11.2 GM (GеMор едишн)

Re: C++ указатели вопрос по ним.

Сообщение Slimy »

wRAR писал(а):
28.09.2006 09:15
(Slimy @ Sep 27 2006, в 16:21) писал(а):
Но если так она объявляется то тогда какая разница между объявлением и использованием значения ведь запись будет одинаковая? *p

Да нет же. Здесь звездочка относится к типу.


Угу только в этом даже примере ниже написано *p=5; И это уже присваивает значение по адресу а не адресс.
wRAR писал(а):
28.09.2006 09:15
(Slimy @ Sep 27 2006, в 16:21) писал(а):
к томуже тип переменной адрес которой хранится в р уже задан при ее объявлении зачем тогда объявлять его еще раз?

Вы объявляете p ровно один раз. А что вы там ему присваиваете - дело десятое. Без указания типа вы переменную не объявите.

Ну для объявления указателей я думал используется специальный тип чтото вроде pointer как в паскале. И тогда стало бы понтяно тчо хранится адресс. А тут выходит что тип переменно имее только значение в том плане сколько ячеек памяти выделить.
wRAR писал(а):
28.09.2006 09:15
(Slimy @ Sep 27 2006, в 16:21) писал(а):
или возможен вариант что переменная int может быть прочитана как допустим float если использовать указатель ?

При работе с классами такое используется сплошь и рядом.

Круто (правда не знаю зачем это может быть нужно).Тогда выходит что тут вы противоречите себе если при прочтеннии учитывается тип указателя т.к. вы сказали в предыдущем посте что это дело десятое.
В общем в итоге выходит из того вы тут говорили по теме первый раз *p= обязательно записывает в себя адресс в остальных случаях должно быть p= , а если дольше применять *p= то будет присваивается значение по адресу храняещемуся в p.
Если уже ничего не помогает - прочти инструкцию.
sysinstall - гадость :)
ASUS A6q00Vm Pentium-M 1.7 GHz, 2Gb RAM, 160Gb HDD,
GeForce Go 7300 64Mb video
Спасибо сказали:
Аватара пользователя
aLexx programmer
Сообщения: 985
Статус: Турук-Макто
ОС: Gentoo -> Ubuntu

Re: C++ указатели вопрос по ним.

Сообщение aLexx programmer »

(Slimy @ Sep 28 2006, в 11:45) писал(а):Угу только в этом даже примере ниже написано *p=5; И это уже присваивает значение по адресу а не адресс.

"int *p;" значит не "объявить переменную *p типа int", а "объявить переменную p типа int*".
Спасибо сказали:
Slimy
Сообщения: 1689
ОС: openSuSE 11.2 GM (GеMор едишн)

Re: C++ указатели вопрос по ним.

Сообщение Slimy »

aLexx programmer писал(а):
28.09.2006 11:56
(Slimy @ Sep 28 2006, в 11:45) писал(а):
Угу только в этом даже примере ниже написано *p=5; И это уже присваивает значение по адресу а не адресс.

"int *p;" значит не "объявить переменную *p типа int", а "объявить переменную p типа int*".

А вот оно что :).спасибо, коротко и четко. Хотя формат записи конечно меня и смутил. Хм тогда еще такое интересно между int* и float* типмаи вообще разница имеется? Или это просто указывается различный объем отводимой памяти т.к. адресс врятли можно считать числом со знаком или с плавающей запятой :unsure: .
Если уже ничего не помогает - прочти инструкцию.
sysinstall - гадость :)
ASUS A6q00Vm Pentium-M 1.7 GHz, 2Gb RAM, 160Gb HDD,
GeForce Go 7300 64Mb video
Спасибо сказали:
wRAR
Сообщения: 372
ОС: ALT Linux Sisyphus

Re: C++ указатели вопрос по ним.

Сообщение wRAR »

(Slimy @ Sep 28 2006, в 13:45) писал(а):Круто (правда не знаю зачем это может быть нужно).

"Подрастете" - читайте про полиморфизм :)

(Slimy @ Sep 28 2006, в 13:45) писал(а):если при прочтеннии учитывается тип указателя т.к. вы сказали в предыдущем посте что это дело десятое.

Это было к тому, что вы, как я понял, решили, что тип переменной-указателя должен получаться из типа того, что мы туда пишем. Это не так.

(Slimy @ Sep 28 2006, в 22:23) писал(а):между int* и float* типмаи вообще разница имеется?

Compile-time checks.

(Slimy @ Sep 28 2006, в 22:23) писал(а):Или это просто указывается различный объем отводимой памяти

Объем как раз одинаковый.
ALT Linux Team
SIM-IM Development Team
Antilamer
Спасибо сказали:
Slimy
Сообщения: 1689
ОС: openSuSE 11.2 GM (GеMор едишн)

Re: C++ указатели вопрос по ним.

Сообщение Slimy »

wRAR писал(а):
30.09.2006 10:20
(Slimy @ Sep 28 2006, в 13:45) писал(а):
Круто (правда не знаю зачем это может быть нужно).

"Подрастете" - читайте про полиморфизм :)



Таки знаком сним. Вернее с перегрузкой функции там как раз нет ничего сложного для понимания. Я вообще С++ занимался (спустя рукава правда) остались большие проблеы пробелы в понимании, которые чтобы двыигатся дальше нужно ликвидировать.
wRAR писал(а):
30.09.2006 10:20
(Slimy @ Sep 28 2006, в 13:45) писал(а):
если при прочтеннии учитывается тип указателя т.к. вы сказали в предыдущем посте что это дело десятое.

Это было к тому, что вы, как я понял, решили, что тип переменной-указателя должен получаться из типа того, что мы туда пишем. Это не так.


Нет я просто не понимаю зачем адрессу вообще тип нужен (скажим так я в дедушке паскале стаким не сталкивался там все проcто pointer) А уж что тип получается из того что мы туда пишем я никогда так не считал.
wRAR писал(а):
30.09.2006 10:20
(Slimy @ Sep 28 2006, в 22:23) писал(а):
между int* и float* типмаи вообще разница имеется?

Compile-time checks.

Хм :) ... этого я пока не знаю
wRAR писал(а):
30.09.2006 10:20
(Slimy @ Sep 28 2006, в 22:23) писал(а):
Или это просто указывается различный объем отводимой памяти

Объем как раз одинаковый.

:blink: мда... удивительное рядом как говорится. видно придется курить много мануалов.
Если уже ничего не помогает - прочти инструкцию.
sysinstall - гадость :)
ASUS A6q00Vm Pentium-M 1.7 GHz, 2Gb RAM, 160Gb HDD,
GeForce Go 7300 64Mb video
Спасибо сказали:
wRAR
Сообщения: 372
ОС: ALT Linux Sisyphus

Re: C++ указатели вопрос по ним.

Сообщение wRAR »

(Slimy @ Sep 30 2006, в 14:34) писал(а):Вернее с перегрузкой функции там как раз нет ничего сложного для понимания.

В таком случае вы должны знать, чем отличается перекрытая виртуальная функция от перекрытой обычной. Отличие там ровно одно и оно непосредственно связано с типами указателей.

(Slimy @ Sep 30 2006, в 14:34) писал(а):Нет я просто не понимаю зачем адрессу вообще тип нужен

Compile-time checks.

(Slimy @ Sep 30 2006, в 14:34) писал(а):в дедушке паскале стаким не сталкивался там все проcто pointer

Там тоже есть типизированные указатели (var a: ^Integer), а в С тоже есть нетипизированные (void*), только это нафик никому не надо как правило, ибо заставляет вручную отслеживать совместимость типов и приведение.

(Slimy @ Sep 30 2006, в 14:34) писал(а):Хм ... этого я пока не знаю

Главная фишка в том, что компилятор не позволит использовать неправильный тип указателя, вот и всё.
ALT Linux Team
SIM-IM Development Team
Antilamer
Спасибо сказали:
Аватара пользователя
Portnov
Модератор
Сообщения: 1786
Статус: Матёрый линуксоид
ОС: Debian testing/unstable

Re: C++ указатели вопрос по ним.

Сообщение Portnov »

Говорите, Паскаль знаете?
Так вот, аналог типа pointer в C++ - это void*, а int* и пр. - это аналоги типизированных указателей (типа var p: ^Int).
Работа: Ubuntu 9.10
Дом: Debian testing/unstable и на всякий случай winxp в virtualbox.
Для разнообразия: моя домашняя страница -http://iportnov.ru
Спасибо сказали:
wRAR
Сообщения: 372
ОС: ALT Linux Sisyphus

Re: C++ указатели вопрос по ним.

Сообщение wRAR »

(Portnov @ Oct 1 2006, в 17:00) писал(а):Так вот, аналог типа pointer в C++ - это void*, а int* и пр. - это аналоги типизированных указателей (типа var p: ^Int).

(wRAR @ Sep 30 2006, в 17:39) писал(а):Там тоже есть типизированные указатели (var a: ^Integer), а в С тоже есть нетипизированные (void*)

Кгхм.
ALT Linux Team
SIM-IM Development Team
Antilamer
Спасибо сказали:
codo
Сообщения: 4
ОС: Windows Xp

Re: C++ указатели вопрос по ним.

Сообщение codo »

#include <iostream>
using namespace std;
int main()
{
int a=2;
int *p=&a;
cout << "*p=" << p << endl; // *p=2
*p=5;
cout << "a=" << a << endl;
return 0;
}


--------------------------------------------------------

int a; : переменная типа int
int * p; : переменная типа указатель на тип int (может содержать адрес переменной типа int)
p = &a; : присвоили адрес переменной a (& - операция взятия адреса)
int b = *p; : переменной типа int присвоили значение, находящееся по адресу p
: (*p - операция разадресации)

---------------------------------------------------------

А ВООБЩЕ, ЕСТЬ ТОЛЬКО ОДИН НАСТОЯЩИЙ ЯЗЫК ПРОГРАММИРОВАНИЯ - ASSEMBLER!!! :)
Спасибо сказали: