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

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 169, средняя оценка - 4.97
Диман56
22 / 22 / 0
Регистрация: 07.11.2011
Сообщений: 154
#1

Понимание для чего вообще нужны указатели? - C++

12.11.2011, 20:12. Просмотров 22951. Ответов 112
Метки нет (Все метки)

Сейчас будет чистый мой тупняк. Слабонервным дальше не читать. Итак, для чего вообще нужны указатели? Я вот не пойму, зачем их надо было вообще придумывать??? Не понимаю их конкретной пользы, смысла. Кто-нибудь может по-человечески объяснить?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.11.2011, 20:12
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Понимание для чего вообще нужны указатели? (C++):

Для чего нужны указатели? - C++
Кто может объяснить для чего нужны указатели и смысл их? в интернете одна муть и еще для чего нужно new delete

Для чего нужны указатели на функции? - C++
для чего нужны эти указатели на функции... не проще ли вызвать саму функцию, чем заводить под нее указатель и им пользоваться...

Ссылки и указатели, для чего нужны те и другие? - C++
Что такое ссылки? Что такое указатели? ДЛЯ чего служат те и другие?

Для чего нужны и зачем использовать smart-указатели? - C++
В Страуструпе не нашел, кто подскжает где можно про них прочитать ?)

Для чего нужны интерфейсы? - C++
Объясните на пальцах для чего нужны интерфейсы, как я понял они описывают методы и свойства, которые при наследовании классами должны были...

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

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Dekio
12.11.2011, 22:36     Понимание для чего вообще нужны указатели?
  #31
 Комментарий модератора 
Прекращаем оффтоп
Диман56
22 / 22 / 0
Регистрация: 07.11.2011
Сообщений: 154
12.11.2011, 22:50  [ТС] #32
Итак, осмелюсь ещё спросить. Точнее, я продолжаю тупить.Объявление:
Код
typedef char M[256];
...
M *folders,*files;
Вот я считаю количество папок и файлов:
Код
while(FindNextFileA(Search, &FileSearch)!=FALSE)
{
if (FileSearch.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
{
i++;
}
else
{
k++;
}
}
Выделяю память:
Код
folders=new M[i];
files=new M[k];
Цикл, в котором надо раскидать по массивам имена файлов и папок:
Код
Search=FindFirstFileA(di, &FileSearch);
FindNextFileA(Search, &FileSearch);
while(FindNextFileA(Search, &FileSearch)!=FALSE)
{
if (FileSearch.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
{
тут что-то
}
else
{
и тут что-то
}
Как мне записать строку?

Добавлено через 9 минут
Уточню, вместо что-то в i-элемент массива должна писаться строка с именем файла или директории.
Bers
Заблокирован
12.11.2011, 22:51 #33
По-моему.. у тебя проблема в том, что тебе свой собственный код трудно прочитать.
Если я прав - тогда упрости его. И сразу видна логика.

Для этого:
1. Избавься от тайдефа. Я уже вижу, что он тебя запутал.
2. Дай переменным более говорящие имена.

Например: имя файла FileName
массив имен файлов FileNameArray, ну или FileNameList

Красивые имена помогают лучше понимать логику
Диман56
22 / 22 / 0
Регистрация: 07.11.2011
Сообщений: 154
12.11.2011, 22:54  [ТС] #34
Хорошо))) Исправлю) Просто проблема в том, что у меня не получается присвоить i-ой строке имя файла. То есть, нужно за раз записать в строку до 256 символов.
diagon
Higher
1929 / 1195 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
12.11.2011, 22:54 #35
А какой у вас язык?
Если С - то без указателей вам никак не обойтись.
Если С++ - можно и не использовать указатели. Более того, в большинстве случаев НЕ нужно использовать указатели.
Ибо в с++ есть такая вещь как STL, которая предоставляет обертки для этих самых указателей. Эти обертки намного более удобны и безопасны, и пользоваться следует именно ими.
mc.Duck
Заблокирован
12.11.2011, 22:56 #36
diagon,хм..а можно поподробнее об обертках?
Bers
Заблокирован
12.11.2011, 22:57 #37
Цитата Сообщение от Диман56 Посмотреть сообщение
Хорошо))) Исправлю) Просто проблема в том, что у меня не получается присвоить i-ой строке имя файла. То есть, нужно за раз записать в строку до 256 символов.
Ты исправь, и исправленный вариант выложи. Там уже в принципе, сразу должно быть видно, где у тебя ошибка в логике.

Плохие имена, и некрасивые тайпдефы могут запросто запутать не только читателя, но и самого автора кода)
Dekio
Фрилансер
Эксперт С++
5837 / 1218 / 214
Регистрация: 23.11.2010
Сообщений: 3,378
Записей в блоге: 1
12.11.2011, 22:57 #38
Цитата Сообщение от mc.Duck Посмотреть сообщение
хм..а можно поподробнее об обертках?
http://ru.wikipedia.org/wiki/%D0%A1%...BD%D0%BE%D0%B2
mc.Duck
Заблокирован
12.11.2011, 22:59 #39
Dekio, благодарю! Об этом знал, но не знал как называется)
Диман56
22 / 22 / 0
Регистрация: 07.11.2011
Сообщений: 154
12.11.2011, 23:05  [ТС] #40
Вот объявление:
Код
const int N=256;....
int FileSum,FolderSum;
char **folders,**files;
Цикл:
Код
while(FindNextFileA(Search, &FileSearch)!=FALSE)
{
if (FileSearch.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
{
FolderSum++;
}
else
{
FileSum++;
}
}
А вот тут на меня компилятор ругается
Код
folders=new char [FolderSum][N];
files=new char[FileSum][N]; //Студия 2010 ругается на знак присваивания.
Bers
Заблокирован
12.11.2011, 23:18 #41
C++
1
2
folders=new char* [FolderSum];
files=new char*[FileSum];
Диман56
22 / 22 / 0
Регистрация: 07.11.2011
Сообщений: 154
12.11.2011, 23:20  [ТС] #42
Спасибо) попробую только завтра-второй час ночи уже. Спасибо за помощь. Ещё вопрос-а размер строки-то как в таком объявлении указывать?)
Bers
Заблокирован
12.11.2011, 23:32 #43
Цитата Сообщение от Диман56 Посмотреть сообщение
Спасибо) попробую только завтра-второй час ночи уже. Спасибо за помощь. Ещё вопрос-а размер строки-то как в таком объявлении указывать?)
Указатель хранит адрес в памяти. Тип указателя - это тип объекта, который по этому адресу живет. Пока все просто.

Но тебе нужно понять ещё одну не очевидную вещь:

По адресу, на который указывает указатель может жить... другой указатель.

И этот другой указатель уже может указывать ещё куда то.


В твоём случае, строка это кусок памяти, который хранит кучку char`ов
Поэтому, можно считать, что указатель , который указывает на кусок памяти, который хранит чары - это и есть строка.

Ну то есть:

char* в твоём отдельно взятом случае можно считать строкой.
Можно даже сделать псевдоним для наглядности:

typedef char* String; //теперь String- это тот же самый char* но воспринимается, как "строка"

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

ты пишешь:

String* МойМассив = new String[количество строк];

это будит равносильно:

char** МойМассив = new char* [количество строк];

На самом деле МойМассив - это указатель, который указывает на кусок памяти, в котором живут другие указатели, которые уже в свою очередь указывают на строки.
Диман56
22 / 22 / 0
Регистрация: 07.11.2011
Сообщений: 154
12.11.2011, 23:34  [ТС] #44
Спасибо вам, все толково объяснено.
Bers
Заблокирован
13.11.2011, 00:33 #45
Напишу вдогонку. Завтра может быть прочитаешь.

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

Сложность такого проекта резко возрастает, соответственно количество потенциальных ошибок увеличивается.

Поэтому, старайся по возможности всегда избегать ситуаций, когда у тебя один указатель указывает на другой. В с++ для этого есть множество решений.

Один из самых простых вариантов - это замаскировать указатель так, что бы он воспринимался не как указатель, а как отдельный тип данных. Например "строка" - это строка, а не "массив чаров".
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
int main()
{
 
    //объявим всему миру,
    //что стековый массив чаров - это String,
    //в который влезет 255 символов
    typedef char String[255]; 
    
    
    //создадим массив String`ов (строк),
    //в который влезет 10 штук строк
 
    //Если бы не было typedef
    //Нам бы пришлось понимать это так:
    //Массив, в который влезет 10 штук других массивов, 
    //каждый из которых вмещает 255 символов.
    
    //Ты уже наверное догадался, что массив - 
    //это ничто иное, как указатель на свой первый элемент
 
    String* myArray= new String[10]; //сделали массив строк
    
    for(int i=0;i<10;++i)
    {
        //запишем данные в массив строк
        memcpy(myArray[i], "Привет, Мир!\0", sizeof(String) );   
        
        //прочитаем каждую строчку и выведем её на экран консоли
        std::cout<<myArray[i]<< std::endl; 
    }
 
    return 0;
}
Другой способ понижения сложности логики - это создание дополнительной сущности, которая инкапсулирует внутри себя знание об указателе:
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
int main()
{
 
    //эту структуру очень просто понять. 
    //Правда ведь?
    struct String 
    {
        char Text[255];
    };
    
    //создаём десять штук таких структур
    String* myArray= new String[10]; 
 
    //Понять что такое структура String
    //И как создать массив структур
    //Намного проще, чем держать уме мысли об указателях,
    // которые указывают на указатели
    //Которые указывают на символы.
 
    //А все что проще - легче сделать
    //И меньше вероятность допустить ошибку
 
    for(int i=0;i<10;++i)
    {
        //запишем данные в массив строк
        memcpy(myArray[i].Text, "Привет, Мир!\0", sizeof(String) );   
        
        //прочитаем каждую строчку и выведем её на экран консоли
        std::cout<<myArray[i].Text<< std::endl; 
    }
 
    return 0;
}
Причем, во втором случае, твоя новая абстрактная сущность - суть новый тип данных.
Это класс. Его можно снабдить удобными методами обработки данных.

Можно сделать метод, который будит загружать данные в массив букв.
Можно сделать метод, который будит все буквы превращать в строчные, или в заглавные.
Ну и тп.

Если ты ещё чуть чуть пройдёшься в этом направлении, то начнешь понимать, что такое классы, оценишь удобства, которые они предоставляют программистам.
Ну а потом, ещё чуть чуть, и ты оценишь всю мощь и великолепие библиотеки STL
Ну а там, ещё годик другой пройдёт, и начнёшь говорить всем, что указатели - фуфло, и нафег они не нужны
Удачи.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.11.2011, 00:33
Привет! Вот еще темы с ответами:

Для чего нужны callback-функции - C++
Для чего нужны callback-функции? И можно привести какой-нибуль пример по их использованию.

Для чего нужны вложенные структуры? - C++
Скажите пожалуйста для чего нужны вложенные структуры и где их используют?

для чего нужны хеш таблицы? - C++
для чего нужны хеш таблицы? если есть массивы )

try catch throw для чего нужны? - C++
Для чего нужны эти операторы? Линканите пожалуйста статью, где доходчиво объяснено их применение, в разных вариантах (например я видел...


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

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

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