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

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 11, средняя оценка - 4.91
Fooly
21 / 17 / 1
Регистрация: 26.03.2012
Сообщений: 147
#1

Недопонимание указателей - C++

03.09.2012, 14:20. Просмотров 1553. Ответов 32
Метки нет (Все метки)

Уже прошёл их по книжке давно, но они частенько встречаются, и я никак не могу понять некоторые процессы с ними.
Допустим есть в классе какие-то данные типа int lim, char name[lim]
Методы принимают указатели допустим Name::Name (const char * nm)
почему при копировании std::strncpy (name, nm, lim-1) мы указываем просто nm, а не *nm ? Ведь nm - это адрес, а само значение это *nm. Т.е по сути в name мы копируем адрес, но всё правильно работает и выводит то, что надо, а не адрес, как я думаю. Поясните плз, что я не таак понимаю
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
03.09.2012, 14:20
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Недопонимание указателей (C++):

Недопонимание кода - C++
Я разбираю некоторый код С++ (Сразу скажу, что учил с++ самостоятельно, не супер профи) и там есть некоторые строчки, которые я не до конца...

Будоражащее недопонимание цикла - C++
#include <iostream> #include <string.h> using namespace std; class Data { public: char f; char l ; ...

по поводу указателей. Как правильно задавать массив указателей и его удалять? - C++
Т.е., например создаю указатель: TPoint *p_Point=NULL; а если массив? TPoint *p_MassPoint; //=?; как массив обнулить не ясно ...

Почему в сортировке указателей на объекты в вызове функции используются адреса объектов, а не указателей? - C++
Доброго времени суток! Рассматриваю пример (из Лафоре) сортировки массива указателей на объекты, для чего используются указатели на...

Объяснить различия в работе указателей на целое число и указателей на const char (строки в стиле Си) - C++
Уважаемые программисты, возникло несколько вопросов касательно указателей. Почему при выводе указателя на int нужна звёздочка (*), а...

Создать специфицированный шаблон функции, принимающей массив указателей на char и количество самих указателей - C++
Задача: создать специфицированный шаблон функции, принимающей массив указателей на char и количество самих указателей. Вернуть адрес...

32
Toshkarik
1148 / 865 / 51
Регистрация: 03.08.2011
Сообщений: 2,404
Завершенные тесты: 1
03.09.2012, 16:39 #16
Цитата Сообщение от IGPIGP Посмотреть сообщение
std::cout<<"\n of ptr_sumb as an address = "<<ptr_sumb;//и тут...
Тут скорей всего будет runtime error. UB тут точно. Что бы вывести значение указателя, рекомендуется приводить его к типу void *.
0
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6911 / 3189 / 315
Регистрация: 04.12.2011
Сообщений: 8,828
Записей в блоге: 5
03.09.2012, 16:45 #17
Цитата Сообщение от Toshkarik Посмотреть сообщение
Тут скорей всего будет runtime error. UB тут точно.
Где-то так. Первый символ - символ A, и хвост из какого-то мусора. Всего 8 символов.
0
Toshkarik
1148 / 865 / 51
Регистрация: 03.08.2011
Сообщений: 2,404
Завершенные тесты: 1
03.09.2012, 16:47 #18
Добавлено через 45 секунд
Цитата Сообщение от IGPIGP Посмотреть сообщение
Всего 8 символов.

Не по теме:

Может быть и 100

2
Intel~lect
135 / 124 / 2
Регистрация: 03.07.2012
Сообщений: 355
03.09.2012, 16:52 #19
Цитата Сообщение от Toshkarik Посмотреть сообщение
Тут скорей всего будет runtime error. UB тут точно.

Не по теме:

Простите за неграмотность. А что означит UB?

0
Toshkarik
1148 / 865 / 51
Регистрация: 03.08.2011
Сообщений: 2,404
Завершенные тесты: 1
03.09.2012, 16:53 #20
Intel~lect, Undefined Behavior.
1
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6911 / 3189 / 315
Регистрация: 04.12.2011
Сообщений: 8,828
Записей в блоге: 5
03.09.2012, 18:59 #21
Цитата Сообщение от Intel~lect Посмотреть сообщение

Не по теме:

Не кажется ли вам, что мы немного от главной темы отошли

Так вроде же объяснили. В моём понимании, функция ожидает две с-строки, по описанию. Через второй ф/параметр передается значение переменной объявленной как char* и если она корректно инициализирована, то является ссылкой и может быть преобразована к с-строке (массиву символов), то есть по сути ею и является. И всё хорошо. Можно конечно изголиться так, что бы и не преобразовать было корректно, но зачем?
0
kotleta
42 / 42 / 11
Регистрация: 13.09.2012
Сообщений: 196
14.09.2012, 16:25 #22
Кстати, а почему так происходит?
Я про пример Hydrogen

Отправили переменную int g себе ее скопировал (положил значение в свою ячейку)
инкрементировался, потом еще инкрементировался
Потом вышли из блока, и память освободилась, и 6 в ячейке памяти осталось, только теперь эта ячейка свободна, и другая переменная ее может использовать.

В чем дело?
0
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6911 / 3189 / 315
Регистрация: 04.12.2011
Сообщений: 8,828
Записей в блоге: 5
14.09.2012, 17:08 #23
Цитата Сообщение от kotleta Посмотреть сообщение
Кстати, а почему так происходит?
Я про пример Hydrogen
Отправили переменную int g себе ее скопировал (положил значение в свою ячейку)
инкрементировался, потом еще инкрементировался
Потом вышли из блока, и память освободилась, и 6 в ячейке памяти осталось, только теперь эта ячейка свободна, и другая переменная ее может использовать.
В чем дело?
Если я понял в чем вопрос:
Сигнатура объявления или заголовок функции:
Тип Имя ( Тип1 <Имя1>, Тип2 <Имя2>, Тип3 <Имя3>....);
В сигнатуре описания:
Тип Имя ( Тип1 Имя1, Тип2 Имя2, Тип3 Имя3....){}
Это не спроста, что здесь Имя1, Имя2, Имя3 должны быть указаны. Потому, что в скобках показано объявление, локальных внутри функции как блока (см. фиг. скобки), переменных. В них функция копирует передаваемые параметры. Независимо от того, значения это или адреса (указатели, ссылки). При копировании, производится преобразование типов, если требуется и возможно.
То есть при передаче значения, функция работает с копией переданного значения, а при передаче указателя, - с копией указателя. Разница в том, что если в функции указатель разыменовывается, то несмотря на то, что указатель - копия, доступ получается к значению переменной на которую он указывает. Тогда если происходит изменения этого значения, то адресуемая указателем переменная изменится везде, где её видно и за пределами функции.
0
OhMyGodSoLong
~ Эврика! ~
1244 / 993 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
14.09.2012, 17:25 #24
Цитата Сообщение от IGPIGP Посмотреть сообщение
Сигнатура объявления или заголовок функции:
Тип Имя ( Тип1 <Имя1>, Тип2 <Имя2>, Тип3 <Имя3>....);
В сигнатуре описания:
Тип Имя ( Тип1 Имя1, Тип2 Имя2, Тип3 Имя3....){}
Это не спроста, что здесь Имя1, Имя2, Имя3 должны быть указаны.
[занудство]
В определении функции тоже можно не именовать аргументы. Естессно, к анонимному параметру тогда (гарантированно и переносимо) достучаться нельзя, но передавать хоть что-то при вызове функции надо. Банальный пример: префиксный и постфиксный инкременты.
[/занудство]
0
Герц
524 / 341 / 4
Регистрация: 05.11.2010
Сообщений: 1,077
Записей в блоге: 1
14.09.2012, 18:26 #25
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
[занудство]
В определении функции тоже можно не именовать аргументы. Естессно, к анонимному параметру тогда (гарантированно и переносимо) достучаться нельзя, но передавать хоть что-то при вызове функции надо. Банальный пример: префиксный и постфиксный инкременты.
[/занудство]
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
void test( int a, int )
{
   int* ptr = &a;
   
   std::cout << *ptr << '\n' << *( ptr + 1 ) << std::endl;
}
 
int main()
{
   test( 123, 456 );
   
   return 0;
}
Имеешь в виду такое? А что тут может быть непереносимого кроме разных calling convention? Ну, наверное, не каждый компилятор будет выделять память под неиспользуемый параметр, но на деле то все выделяют.
0
OhMyGodSoLong
~ Эврика! ~
1244 / 993 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
14.09.2012, 18:56 #26
Цитата Сообщение от Герц Посмотреть сообщение
Имеешь в виду такое? А что тут может быть непереносимого кроме разных calling convention? Ну, наверное, не каждый компилятор будет выделять память под неиспользуемый параметр, но на деле то все выделяют.
Ага, именно это и именно из-за протоколов вызова. За компилятором же остаётся право не только вычислять аргументы в том порядке, в каком ему нравится, но и размещать их в памяти так, как ему нравится. То есть не факт, что они будут идти именно так, как в списке аргументов.
0
Герц
524 / 341 / 4
Регистрация: 05.11.2010
Сообщений: 1,077
Записей в блоге: 1
14.09.2012, 19:01 #27
VC++ compiler развращает своими __stdcall, __thiscall и т.п. :-)
0
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6911 / 3189 / 315
Регистрация: 04.12.2011
Сообщений: 8,828
Записей в блоге: 5
14.09.2012, 19:26 #28
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
[занудство]
В определении функции тоже можно не именовать аргументы. Естессно, к анонимному параметру тогда (гарантированно и переносимо) достучаться нельзя, но передавать хоть что-то при вызове функции надо. Банальный пример: префиксный и постфиксный инкременты.
[/занудство]
Конечно, не боевик! Что и говорить. Но я попробовал ответить (угадать что ответить) kotleta на вопрос:
Цитата Сообщение от kotleta Посмотреть сообщение
Кстати, а почему так происходит?
Я про пример Hydrogen
Отправили переменную int g себе ее скопировал (положил значение в свою ячейку)
инкрементировался, потом еще инкрементировался
Потом вышли из блока, и память освободилась, и 6 в ячейке памяти осталось, только теперь эта ячейка свободна, и другая переменная ее может использовать.
В чем дело?
Мы же в разделе новичков и нужно, что бы всем было понятно.
Вот, фрагмент вызвавший вопрос:
Цитата Сообщение от Hydrogen Посмотреть сообщение
Указатели нужны еще и потому, что изменения, которые происходят в
C++
1
2
3
4
5
{
   *g++;// g равно 5
   *g++;// g равно 6
   return 0;
}// а теперь g равно 6
Как я понял вопрос, так и ответил.
Хотя вопрос бы мог и так звучать:
Приоритет ++ выше чем у разадресации. То есть сначала передвинули указатель, а потом разадресовали?
Думаю, - механическая ошибка. Имелось в виду:
C++
1
2
3
4
5
{
   (*g)++;// g равно 5
   (*g)++;// g равно 6
   return 0;
}// а теперь g равно 6
1
Toshkarik
1148 / 865 / 51
Регистрация: 03.08.2011
Сообщений: 2,404
Завершенные тесты: 1
14.09.2012, 19:34 #29
Да, у постфиксного инкремента/декремента приоритет выше. Но тут можно запутаться, поэтому лучше всегда ставить скобки. Например при префиксном инкременте/декременте если знак операции стоит слева от знака разыменования, то сначала будет получен объект, и потом к нему будет применена операция инкремента.
C++
1
2
3
++*g; //тут происходит операция инкремента объекта
*++g; //тут уже будет инкремент указателя
*g++; //ну а тут будет только инкремент указателя
1
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6911 / 3189 / 315
Регистрация: 04.12.2011
Сообщений: 8,828
Записей в блоге: 5
14.09.2012, 19:44 #30
Цитата Сообщение от Toshkarik Посмотреть сообщение
C++
1
*g++; //ну а тут будет только инкремент указателя
Боюсь не только. После инкремента указателя, еще чтение по адресу в анонимную переменную. То есть, есть подозрение, что если много раз подряд, так сделать (непреднамеренно), в цикле например, то можно получить ошибку защиты. Или нет?
0
14.09.2012, 19:44
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
14.09.2012, 19:44
Привет! Вот еще темы с ответами:

Создать специализацию для шаблона, которая принимает массив указателей на строки и количество этих указателей - C++
Нужно создать специализацию для шаблона, которая принимает массив указателей на строки и количество этих указателей. Эта специализация...

Недопонимание с switch и выводом default - C++
Задание: сделать так что бы при вводе целого числа (от 1 до 7 которые соответствует дням недели, 1- понедельник, 2 -вторник и т.д.)...

Как обойтись без указателей и указателей на указатель? - C++
Ибо не совсем выходит понять,что на что тут указывает #include &quot;stdafx.h&quot; #include &lt;iostream&gt; #include &lt;stdlib.h&gt; using namespace...

Различия указателей char* от указателей других типов - C++
Помогите пожалуйста разобраться! Прочитал раздел про указатели и даже вроде бы понял. Что касается указателей на тип int. Но что...


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

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

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