Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 27.06.2013, 14:16   #1
blackalegator
Новичок
Джуниор
 
Регистрация: 27.06.2013
Сообщений: 1
По умолчанию Ссылки и указатели. Перехожу на с++ с Java

Всем привет. Знаю, эта тема поднималась уже не раз, но я так и не смог найти ответы на мои вопросы.
"В чем различие ссылок и адресов переменной?"
"Есть ли разница между int* a или int *a?"
"Как взаимосвязаны указатели и адреса переменной? Если у меня есть указатель a, я могу работать с a используя *a, но если у меня есть адрес на некий объект, как работать с этим объектом через ссылку?"
"Объявления в с++. ClassA* a = new ClassA(); Можно ли изначально объявить переменную типа ClassA (не указатель) а потом его инициализировать?"
(Пример)
ClassA a;
a = new ClassA();
"Когда в функции входной параметр - указатель или адрес, а у меня самого адрес или указатель я начинаю методом тыка перед указателем(ссылкой) ставить * и &. Иногда помогает, иногда нет. Как быть?"
"При объявлении массивов в чем разница между char a[4] и char* a= new char[4];?"

Для меня это единственная больная тема в с++. Она заставляла меня не раз закрывать VS и не вспоминать о C++ еще 3 дня. Помогите разобраться, пожалуйста

Последний раз редактировалось blackalegator; 27.06.2013 в 14:37.
blackalegator вне форума Ответить с цитированием
Старый 27.06.2013, 15:06   #2
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от blackalegator Посмотреть сообщение
"В чем различие ссылок и адресов переменной?"
ссылка - это синоним имени некоторой переменной.
Все действия над ссылкой - это на самом деле действия над оригинальным объектом.

Поэтому, ссылка не обладает идентичностью. Это единственный тип данных на языке с++, у которого отсутствует объект.
Поэтому, у ссылки нельзя взять адрес.

Попытка взять адрес ссылки приведет к тому, что вы получите адрес оригинального объекта.

грубо говоря:

Код:
int val=10;
int& val1 = val;

//по факту существует только один объект типа int
//val и val1 это два имени одного и того же объекта

А адрес переменной - это адрес куска памяти, где расположен сам объект который ассоциирован с именем этой переменной

Цитата:
Сообщение от blackalegator Посмотреть сообщение
"Есть ли разница между int* a или int *a?"
Разницы нет. Это дело вкуса.
Вообще то, ответы на подробные вопросы есть в любой книжке для самых маленьких.

Цитата:
Сообщение от blackalegator Посмотреть сообщение
"Как взаимосвязаны указатели и адреса переменной?
Указатель - это такая же полноценная переменная. Которая внутри себя хранит адрес другой переменной:

Код:
int val = 10;
int* pval = &val; //указатель хранит адрес переменной val
//при этом, по типу указателя, компилятор знает, 
//что там хранится объект типа int
Цитата:
Сообщение от blackalegator Посмотреть сообщение
Если у меня есть указатель a, я могу работать с a используя *a, но если у меня есть адрес на некий объект, как работать с этим объектом через ссылку?"
Код:
#include <iostream>

int main()
{
    int val = 10;
    int pval = &val;
    int& rval = val;

    *pval = 20; //через указатель изменяем значение val на 20

    rval +=10; //через ссылку увеличиваем значение val на 10

    std::cout<<" val = "<< val<<std::endl; //должно высветится val = 30
    return 0;
}

Цитата:
Сообщение от blackalegator Посмотреть сообщение
"Объявления в с++. ClassA* a = new ClassA(); Можно ли изначально объявить переменную типа ClassA (не указатель) а потом его инициализировать?"
(Пример)
ClassA a;
a = new ClassA();
Можно сделать:
Код:
ClassA a; //создаем объект класса ClassA
ключевое слово new используется только в трех ситуациях:
1. Создание объекта в куче
2. Создание объекта по указанному адресу new placement
3. создание объекта при помощи своего собственного аллокатора памяти

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

Код:
ClassA a; //создание экземпляра класса на стеке
ClassA* p = new ClassA; //создание экземпляра класса в куче
На первых порах тебе этого хватит за глаза.

Цитата:
Сообщение от blackalegator Посмотреть сообщение
"Когда в функции входной параметр - указатель или адрес, а у меня самого адрес или указатель я начинаю методом тыка перед указателем(ссылкой) ставить * и &. Иногда помогает, иногда нет. Как быть?"
1. Можно взять в руки учебник по языку с++ и выучить материал.

2. Можно кодить по принципу глупой мартышки - тупым бездумным перебором.

3. Можно сменить роль деятельности, и например стать продавцом-консультантом.



Цитата:
Сообщение от blackalegator Посмотреть сообщение
"При объявлении массивов в чем разница между char a[4] и char* a= new char[4];?"
Код:
char a1[4]; //массив типа char вмещающий 4 элемента

char* a2= new char[4]; //указатель на объект типа char

//во втором случае не существует никакого массива
//существует указатель, который нацелен на область в динамической памяти, способную вместить в себя 4 элемента типа char
_Bers вне форума Ответить с цитированием
Старый 27.06.2013, 22:37   #3
SAMOUCHKA
Форумчанин
 
Регистрация: 07.08.2011
Сообщений: 576
По умолчанию

на сколько я знаю в джаве все объекты создаются динамически, в плюсах не так. если ты объявил указатель и попытаешься изменить значение по этому адресу будет ошибка времени исполнения. и не забывай память освободить, если динамически выделил.
SAMOUCHKA вне форума Ответить с цитированием
Старый 27.06.2013, 22:41   #4
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от SAMOUCHKA Посмотреть сообщение
если ты объявил указатель и попытаешься изменить значение по этому адресу будет ошибка времени исполнения.
Неужели?

Код:
#include<iostream>
int main()
{
    int val=10;
    int* pval = &val;
    *pVal = 20;
    std::cout<<"val = "<< val<<std::endl;
    return 0;
}
_Bers вне форума Ответить с цитированием
Старый 28.06.2013, 10:14   #5
SAMOUCHKA
Форумчанин
 
Регистрация: 07.08.2011
Сообщений: 576
По умолчанию

я имел в виду это:
Код:
int *p; // ни кто не знает значение адреса
*p = 20;// компилятор такое пропустит, но программа закроется
проверял и на виндовс и линукс. ОС не дает работать с произвольным адресом

вообще если хочешь разобратся с указателями рекомендую написать класс "связный список", опыту наберешся

Последний раз редактировалось SAMOUCHKA; 28.06.2013 в 10:41.
SAMOUCHKA вне форума Ответить с цитированием
Старый 28.06.2013, 10:16   #6
Bugrimov
C/C++, Java
Участник клуба
 
Аватар для Bugrimov
 
Регистрация: 28.03.2012
Сообщений: 1,680
По умолчанию

Почему SAMOUCHKA не будет работать???
Что происходит в этом коде??
"Keep it simple" - придерживайтесь простоты!
Уильям Оккам - "Не следует множить сущее без необходимости"
Сложность - враг простоты и удобства!
Bugrimov вне форума Ответить с цитированием
Старый 28.06.2013, 10:33   #7
SAMOUCHKA
Форумчанин
 
Регистрация: 07.08.2011
Сообщений: 576
По умолчанию

ошибки в коде нет. Ты объявил указатель. Указатель это переменная хранящая адрес, когда его объявил она хранит случайный адрес. И ты пытаешся изменить значение по этому адресу. На сколько знаю такое прокатывало на win98, начиная с xp такое не проходит. попробуй скомпилируй и запусти, увидишь что произойдет
SAMOUCHKA вне форума Ответить с цитированием
Старый 28.06.2013, 11:03   #8
Bugrimov
C/C++, Java
Участник клуба
 
Аватар для Bugrimov
 
Регистрация: 28.03.2012
Сообщений: 1,680
По умолчанию

Код:
*p = 20;
Компилятор к операциям разыменование относится спокойно.
"начиная с xp такое не проходит"
Или вы думаете - это первые шаги машин к завоеванию и порабощению человечества.
"Keep it simple" - придерживайтесь простоты!
Уильям Оккам - "Не следует множить сущее без необходимости"
Сложность - враг простоты и удобства!
Bugrimov вне форума Ответить с цитированием
Старый 28.06.2013, 12:27   #9
SAMOUCHKA
Форумчанин
 
Регистрация: 07.08.2011
Сообщений: 576
По умолчанию

Цитата:
Сообщение от Bugrimov Посмотреть сообщение
Код:
*p = 20;
Компилятор к операциям разыменование относится спокойно.
"начиная с xp такое не проходит"
Или вы думаете - это первые шаги машин к завоеванию и порабощению человечества.
компилятор в таких случаях ошибку не видит, ибо это не протеворечит С++
Код:
int *p; // ни кто не знает значение адреса
*p = 20;// компилятор такое пропустит, но программа закроется
нет не думаю.
Но согласитесь это хорошо что современные ОС не дают изменить значение по произвольному адресу. Вдруг этот участок памяти занят другой программой, тогда результат будет непредсказуем

Последний раз редактировалось SAMOUCHKA; 28.06.2013 в 12:29.
SAMOUCHKA вне форума Ответить с цитированием
Старый 28.06.2013, 13:07   #10
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,285
По умолчанию

Цитата:
Сообщение от SAMOUCHKA Посмотреть сообщение
Но согласитесь это хорошо что современные ОС не дают изменить значение по произвольному адресу. Вдруг этот участок памяти занят другой программой, тогда результат будет непредсказуем
Архитектура памяти в Windows - у каждой программы свое адресное пространство. Но свою программу определенно можно порушить.
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
указатели и ссылки Trampcher Visual C++ 1 02.06.2013 21:27
указатели и ссылки syrga Общие вопросы C/C++ 10 18.01.2012 06:19
Перехожу с Delphi на Java. Нужна литература Mr_freeman Общие вопросы по Java, Java SE, Kotlin 1 11.10.2011 14:55
указатели vs ссылки Aistn Общие вопросы C/C++ 9 01.06.2011 23:02
ссылки и указатели. mojohead Помощь студентам 13 14.01.2011 16:00