Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.70/56: Рейтинг темы: голосов - 56, средняя оценка - 4.70
 Аватар для Svid
5 / 5 / 2
Регистрация: 02.03.2011
Сообщений: 40

Понять указатели:)

10.03.2011, 13:35. Показов 11320. Ответов 55
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день!
Совсем недавно начал изучать С++, в основном по методичке, выданной в ВУЗе и по нескольким книгам (Страуструп Б., Стефан Дэвис) и плюс то, что нахожу в интернете. Практически, всё это привязано к ряду лабораторных и контрольных, которые необходимо сделать.
Дошел до указателей....О_о. Проблема вот в чем: те практические примеры, которые показывают использование указателей, не отвечают на вопрос - зачем? То есть, все что сделано в этих примерах с помощью указателей, можно сделать и без них, и нельзя сказать, что это будет сложнее. Из-за этого очень трудно понять смысл указателей и они для меня пока что пустая абстракция.
Есть ли какие-нибудь простые практические примеры, показывающие... почему без указателей не обойтись? Например, очень легко практически объяснить суть цикла или там функции.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
10.03.2011, 13:35
Ответы с готовыми решениями:

Указатели не могу понять
Все вопросы указал в комментариях к коду. Не могу понять почему так #include <iostream> using namespace std; int main() { ...

Не могу понять зачем нужны указатели?
Не как не могу понять зачем нужны указатели. Я знаю что их надо использовать для выделения памяти, но раньше я и без них обходился

Строки (массив char), указатели. Не могу понять логику! Help!
Вообщем проблема в том что выводятся лишние символы в строках.. хотя в них есть признак окончания строк - нулевой байт я новичок в С...

55
 Аватар для pepsikat
293 / 14 / 3
Регистрация: 21.12.2010
Сообщений: 293
10.03.2011, 13:55
Указатели используют для динамического выделения памяти. Ну вот например, есть у Вас какой-либо объект представленный структурой, а сколько этих объектов не известно, т.е. массив использовать нельзя. Вот тут-то и приходят на помощь указатели.

Допустим тебе необходимо из функции массив вернуть, или наоборот в функцию массив из 1000000 float'ов передать. Через параметр - накладно. Нудо использовать указатель на массив.

Указатели вещь нужная, так что лучше хорошо с ними разберись
0
Эксперт С++
5058 / 3118 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
10.03.2011, 13:59
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <stdio.h>
 
void real_swap(int *a, int *b)
{
    int temp = *a;
    *a = *b;
    *b = temp;
 
    printf("In real swap:   \ta = %d\tb = %d\n", *a, *b);
}
 
void image_swap(int a, int b)
{
    int temp = a;
    a = b;
    b = temp;
 
    printf("In image swap:  \ta = %d\tb = %d\n", a, b);
}
 
int main(void)
{
    int a, b;
 
    printf("Enter a: ");
    scanf("%d", &a);
    printf("Enter b: ");
    scanf("%d", &b);
 
    printf("Before image swap:\ta = %d\tb = %d\n", a, b);
    image_swap(a, b);
    printf("After image swap:\ta = %d\tb = %d\n", a, b);
 
    printf("Before real swap:\ta = %d\tb = %d\n", a, b);
    real_swap(&a, &b);
    printf("After real swap:\ta = %d\tb = %d\n", a, b);
 
    return 0;
}
2
 Аватар для Svid
5 / 5 / 2
Регистрация: 02.03.2011
Сообщений: 40
10.03.2011, 14:24  [ТС]
А что делает эта программа? Что такое swap?
0
Эксперт С++
5058 / 3118 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
10.03.2011, 14:29
Swap обменивает переменные местами. Суть в том, что без использования указателей совершить действия над переменными вызывающей функции внутри вызываемой невозможно, поскольку при передаче параметров в функцию их значения копируются в собственные локальные переменные этой функции и все действия совершаются над ними. Когда же мы передаём адреса, то вызываемая функция может работать с теми же значениями, что и вызывающая, и все изменения будут происходить над реальными переменными, а не над их копиями. В данном случае image_swap принимает значения, и, хотя в функции обмен переменных произошёл, сами переменные в вызывающей функции (main) остались неизменными, поскольку в image_swap происходил обмен местами лишь копий реальных значений. В real_swap же на вход идут адреса, а через них мы получаем доступ к оригинальным переменным, которые и меняем местами. В main после вызова real_swap значения действительно поменялись.
2
Freelance
Эксперт С++
 Аватар для asics
2891 / 1826 / 356
Регистрация: 09.09.2010
Сообщений: 3,841
10.03.2011, 14:31
Цитата Сообщение от silent_1991 Посмотреть сообщение
Суть в том, что без использования указателей совершить действия над переменными вызывающей функции внутри вызываемой невозможно,
А как же
C++
1
void swap(int &, int &);
?
1
Эксперт С++
5058 / 3118 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
10.03.2011, 14:33
А мы что, говорим о ссылках?
0
Freelance
Эксперт С++
 Аватар для asics
2891 / 1826 / 356
Регистрация: 09.09.2010
Сообщений: 3,841
10.03.2011, 14:35
silent_1991, Ну Вы написали
Цитата Сообщение от silent_1991 Посмотреть сообщение
Суть в том, что без использования указателей совершить действия над переменными вызывающей функции внутри вызываемой невозможно
как бы - возможно.
0
Эксперт С++
5058 / 3118 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
10.03.2011, 14:37
Как бы да. Но если человек не прошёл ещё указатели, о каких ссылках речь? Некоторые конечно дают сначала ссылки, строки, массивы, а потом указатели, но, ИМХО, это неверный подход.

P.S. Я понимаю, вы констатируете факт - возможно. Спасибо, я тоже об этом помню. Но в данный момент нас интересуют указатели и их возможное применение.
0
 Аватар для Svid
5 / 5 / 2
Регистрация: 02.03.2011
Сообщений: 40
10.03.2011, 14:47  [ТС]
Спасибо!
Пытаюсь разобраться...
Наверное, у меня еще слишком большие пробелы в теории

С printf и scanf еще не знаком, я так понял, это тоже функции ввода-вывода (кстати, почему компилятор ругается на scanf?) .
scanf("%d", &a) - это читает десятичное целое и - &a - что это?

Наверное, почти такой же пример приведен в методичке:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>  
     void change(int *x,int *y) // описание ф-ции с фоpмальными
                    // паpаметpами указателями
             { int c = *x;
               *x = *y;
               *y = c;
             }
     void chan(int& x,int& y)   // описание ф-ции с фоpмальными
                    // паpаметpами типа ссылка
             { int c = x;
               x = y;
               y = c;
             }
     void main()
          { int a = 1;
        int b = 0;
        change(&a,&b);    // пеpедача фактических паpаметpов
                  // в виде адpесов
        std::cout<< "\na= "<< a << "\t b= "<< b; // a= 0   b= 1
        chan(a,b);        // пеpедача фактических паpаметpов
                  // в виде пеpеменных
        std::cout<< "\na= "<< a << "\t b= "<< b; // a= 1   b= 0
          }
и он тоже мне пока не понятен
0
Эксперт С++
5058 / 3118 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
10.03.2011, 15:25
Да, пример точно такой же. Можете с принтэф/сканэф не заморачиваться пока, раз на плюсах пишете. А что вам конкретно в этих примерах не понятно?
0
9 / 9 / 4
Регистрация: 04.03.2010
Сообщений: 40
10.03.2011, 15:59
Я только перетек с Delphi на C++( вернее начал перетекать ). Читая книжку по С++ столкнулся с такой же проблемой, было сказано, что такое указатели, но зачем они нужны не объяснялось, и это осталось для меня загадкой.

И , о чудо, зайдя на форум, наткнулся на эту тему, которые уж было сам хотел создавать

Теперь до меня вроде дошло, для чего нужно использование указателей
Итак (если что, поправьте ):

1) В случае использования передачи параметров в виде переменных, аргументам функции присваивается значение передаваемых переменных, тем самым создавая новые переменные, область видимости которых - функция. И меняются значения созданных внутри функции переменных, а значения переменных, передаваемых аргументами никак не изменяется, ибо они лишь однажды передали свои значения для переменных функции.

2) Когда используются указатели в качестве аргументов, аргументы функции принимают не численное значение передаваемых переменных( в данном случае a и b ), а ссылку на ячейки памяти, содержащих значение этих переменных, и внутри функции орудуют уже не новыми переменными, а значениями, хранящимися в адресах, принимаемых в качестве аргументов.

Но у меня остался другой вопрос по этой теме: при создании экземпляра класса в чем разница между использованием указателя и простым созданием объекта? Это связанно с стеком и кучей? Если да, то каким образом?
1
Эксперт С++
5058 / 3118 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
10.03.2011, 16:08
Да, про формальные и фактические параметры вы всё правильно поняли.
Теперь второй вопрос: если вы имеете ввиду, в чём разница между динамическим выделением памяти под объект с помощью оператора new и работой с этой памятью через указатель на объект данного типа и простым созданием объекта - то разница такая же, как и между созданием статического и динамического массива - один создаётся в стеке и автоматически уничтожается, второй - в куче и освобождаться должен пользователем.
1
40 / 38 / 5
Регистрация: 22.01.2011
Сообщений: 670
10.03.2011, 16:16
и дополню. при создании указателя выделяется всегда 4 байта (32-я система), а при создании обьекта выделяется память, в зависимости от типа обьекта. Указатель можно переназначить на другую переменную, а имя обьекта нельзя.
0
 Аватар для Svid
5 / 5 / 2
Регистрация: 02.03.2011
Сообщений: 40
10.03.2011, 17:14  [ТС]
Еще раз всем спасибо!!! Многое стало понятно, особенно после поста Feax.

А что вам конкретно в этих примерах не понятно?
Не то чтобы непонятно, а скорее - я просто не могу для себя внятно вербализировать то, что делают эти примеры. Ну, то есть, если взять какой-нибудь цикл
C++
1
2
3
4
5
sUmm=0;
for (i=1;i<=mPoslednay;i++)
for (j=1;j<=nPredposlednay;j++)
{
sUmm=sUmm +(2*i+j);}
я могу своими словами пошагово объяснить что там происходит)), в примерах с указателями - нет.
0
Эксперт С++
5058 / 3118 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
10.03.2011, 17:22
А вы пытались запустить программу, которую я выкладывал?
0
 Аватар для Svid
5 / 5 / 2
Регистрация: 02.03.2011
Сообщений: 40
10.03.2011, 17:31  [ТС]
Да, конечно.
Мне просто не понятны подписи к выводу ( с английским плохо):
Before image swap
In image swap и т.д.

Более того, я в том примере, который из моей методички, убирал указатели ( и ссылки), вызывая функцию с параметрами переменных (a и b), и вот это:
1) В случае использования передачи параметров в виде переменных, аргументам функции присваивается значение передаваемых переменных, тем самым создавая новые переменные, область видимости которых - функция. И меняются значения созданных внутри функции переменных, а значения переменных, передаваемых аргументами никак не изменяется, ибо они лишь однажды передали свои значения для переменных функции.

2) Когда используются указатели в качестве аргументов, аргументы функции принимают не численное значение передаваемых переменных( в данном случае a и b ), а ссылку на ячейки памяти, содержащих значение этих переменных, и внутри функции орудуют уже не новыми переменными, а значениями, хранящимися в адресах, принимаемых в качестве аргументов.
мне понятно...
но вербализовать, то что делают примеры, я не могу. Наверное, дело в том, что до этого с понятием "памяти" я не сталкивался...
0
Эксперт С++
5058 / 3118 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
10.03.2011, 17:36
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <stdio.h>
 
void real_swap(int *a, int *b)
{
    int temp = *a;
    *a = *b;
    *b = temp;
 
    printf("Реальный обмен местами:\ta = %d\tb = %d\n", *a, *b);
}
 
void image_swap(int a, int b)
{
    int temp = a;
    a = b;
    b = temp;
 
    printf("Мнимый обмен местами:\ta = %d\tb = %d\n", a, b);
}
 
int main(void)
{
    int a, b;
 
    printf("Введите a: ");
    scanf("%d", &a);
    printf("Введите b: ");
    scanf("%d", &b);
 
    printf("До мнимого обмена:  \ta = %d\tb = %d\n", a, b);
    image_swap(a, b);
    printf("После мнимого обмена: \ta = %d\tb = %d\n", a, b);
 
    printf("До реального обмена:  \ta = %d\tb = %d\n", a, b);
    real_swap(&a, &b);
    printf("После реального обмена:\ta = %d\tb = %d\n", a, b);
 
    return 0;
}
2
 Аватар для Svid
5 / 5 / 2
Регистрация: 02.03.2011
Сообщений: 40
10.03.2011, 18:45  [ТС]
Да, очень наглядно.
Но - чувствую себя полным гуманитарием.
Я думаю, что на этом этапе мне пока не понять - зачем нужны указатели, даже Ваш пример на этот вопрос до конца не отвечает - ведь если реализовать это
C++
1
2
3
int temp = a;
    a = b;
    b = temp;
не в теле функции image_swap, а в main то, произойдет реальный обмен... без указателей, ну понятно, что они нужны не для того, чтобы менять значения переменных. Видимо, надо двигаться дальше, а полное понимание придет со временем
Еще раз всем спасибо!
1
Эксперт С++
5058 / 3118 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
10.03.2011, 18:54
Обмен переменных - лишь пример, который показывает, что без указателей в случае, когда в функции надо изменить фактические параметры, не обойтись (про ссылки пока не говорим).

Цитата Сообщение от Svid Посмотреть сообщение
ведь если реализовать это не в теле функции image_swap, а в main то, произойдет реальный обмен
А если у вас в сотне разных мест программы, состоящей из 5000 строк кода, происходит обмен значений? Что, будем писать 200 лишних строчек только потому, что упрямо не желаем согласиться, что даже в такой маленькой функции указатели ого-го как пригодились?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
10.03.2011, 18:54
Помогаю со студенческими работами здесь

Символьные литералы, указатели и функция. Не могу понять, почему именно так
Доброго времени суток всем! :) Изучаю С++, всегда стараюсь добить до последнего код, чтобы не было непоняток. Но сейчас наткнулся на...

Не могу понять, как "живут" файловые указатели
Не могу понять как живут файловые указатели... Есть у меня файл, и пишу в него 100 интов. Указатель ввода сдвигается на 400, так и надо....

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

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

Почему Лафоре использует указатели на указатели, вместо обмена значениями указателей?
Доброго времени суток! Задался теоретическим вопросом. Читал пример из книги Лафоре ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ В C++,...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru