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

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

Войти
Регистрация
Восстановить пароль
 
артист
3 / 5 / 4
Регистрация: 17.09.2014
Сообщений: 710
Завершенные тесты: 1
#1

Как пользоваться указателями строк? - C++

07.01.2016, 00:02. Просмотров 280. Ответов 7
Метки нет (Все метки)

Задолбался уже с вычислением длины строки:

eLen[0] - это длина текста.
Мне нужно добить эту длину до кратности 16, умножить на 2 и прибавить 16.

Ну бред уже просто начался...
C++
1
BYTE * bDataOut = new BYTE[eLen[0] - ((eLen[0] % 16) - 16) * 2 + 16];
Если строка = 3:
3 - (3 - 16) * 2 + 16 = 48

А если я вот так оставлю:
C++
1
BYTE * bDataOut;
Это будет что значить? Один байт?
Что означает эта звёздочка?
Как мне сделать проще?
Мне нужно потом с ячейками работать...
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.01.2016, 00:02
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Как пользоваться указателями строк? (C++):

Как пользоваться потоком строк - C++
Как stringstream-ом получить поток строк, а потом все их, не смешав, записать в массив строк?

Пользователькие функции, работа с указателями и обработка строк - C++
Помогите решить задачи в С++ (я в этом начиющий): 1)Вывести на экран таблицу степеней двойки: 2, где n изменяется от -к до 10. Операцию...

Как избавиться от * и . при работе с указателями? - C++
Сразу приведу пример: #include <stdio.h> struct struct5 { int* value; }; struct struct4 { struct5* s5; };

Подскажите хороший компилятор, как его установить, как им пользоваться? - C++
Подскажите хороший компилятор, как его установить, как им пользоваться??

Как создать 2-ое дерево со значениями 1-го? Не могу разобраться с указателями - C++
Вот код(недоработанный): #include <iostream> #include <cstdlib> #include <ctime> using namespace std; struct sNode { int...

Прога написана с указателями,как указатели заменить ссылками - C++
Доброго времени суток. Прога написана с указателями,как указатели заменить ссылками? #include <iostream> #include <ctime> ...

7
castaway
Эксперт С++
4884 / 3019 / 370
Регистрация: 10.11.2010
Сообщений: 11,078
Записей в блоге: 10
Завершенные тесты: 1
07.01.2016, 00:19 #2
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от артист Посмотреть сообщение
Что означает эта звёздочка?
Указатель.

Цитата Сообщение от артист Посмотреть сообщение
Как мне сделать проще?
Понятным языком объяснить проблему.

Цитата Сообщение от артист Посмотреть сообщение
Мне нужно добить эту длину до кратности 16, умножить на 2 и прибавить 16.
Если я не ошибаюсь, то округлить вверх можно так: i = (i + 15) / 16 * 16;
1
артист
3 / 5 / 4
Регистрация: 17.09.2014
Сообщений: 710
Завершенные тесты: 1
07.01.2016, 02:01  [ТС] #3
Цитата Сообщение от castaway Посмотреть сообщение
Указатель.
А чем он отличается от BYTE bDataOut; ?

Я уже гуглил, везде указатель, указатель, а что он делает и зачем он, не пишут...

Вот так, я понимаю создастся 1 элемент:
C++
1
BYTE bDataOut;
А так, сколько?:
C++
1
BYTE * bDataOut;
Цитата Сообщение от castaway Посмотреть сообщение
Понятным языком объяснить проблему.
Мне нужно считать текст из окна EDIT, зашифровать его в AES и вывести текстом как hex в другое окно.

Пока что вот такое г получилось:
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
40
41
42
43
44
45
BYTE bDataBlocks[crypto.block_size] = {0};      // Буффер для шифрования, 16 ячеек
 
WCHAR * wTextIn = new WCHAR[eLen[0]];           // Массив под текст(ввод)
GetWindowTextW(hEdit[1], wTextIn, eLen[0] + 1); // Получить текст из поля(без нуль терминатора)
 
BYTE * bDataIn = new BYTE[eLen[0] * 2];                                     // Массив под данные(ввод), в него копируется весь текст
std::copy(wTextIn, wTextIn + eLen[0], reinterpret_cast<WCHAR *>(bDataIn));  // Копировать двух байтовую строку в массив байт
 
BYTE * bDataOut = new BYTE[eLen[0] - ((eLen[0] % 16) - 16) * 2 + 16];       // Массив под данные(вывод), в него копируются шифрованные данные
 
unsigned long long llDataLenght = eLen[0];      // Длина всего текста
 
for(int i = 0; i < 8; ++i) bDataBlocks[i] = llDataLenght >> (i * 8); // Записать длину текста в буфер побайтово
 
(crypto.*whats_to_do)(bDataBlocks, bDataBlocks);    // Шифровать 1й блок
 
unsigned chunk = -1;    // Счётчик. потом + 16 - для записи потому, что записан 1й блок
 
while(++chunk < 16) bDataOut[chunk] = bDataBlocks[chunk];   // Копировать 1й блок
//memcpy(wTextOut, bDataBlocks, 16 * sizeof(BYTE)); // Записать 1й блок
 
while(chunk < eLen[0]) // Цикл, пока не кончатся данные
{
    for(int j = 0, i = (chunk - 16); i < chunk; ++i)    // Копировать данные по 16 байт в буффер
    {
        if(i < eLen[0]) // Если данные не кончились
        {
            bDataBlocks[i] = bDataIn[i];    // Копировать данные
            j++;                            // Считать скопированные данные
        }
        else if(j < 15) // Если данные кончились, а буффер заполнен не до конца
        {
            while(j < 16)   // Дополнить буффер до конца
            {
                bDataBlocks[j] = 0; // Копировать ноль
                j++;                // Считать скопированные данные
            }
            break;  // Разрушить цикл копирования в буффер
        }
        else break; // Если данные закончились и буффер полностью забит, разрушить цикл копирования в буффер
    }
    (crypto.*whats_to_do)(bDataBlocks, bDataBlocks);    // Шифровать блок
    
    for(int i = chunk; i < (chunk += 16); ++i) bDataOut[chunk] = bDataBlocks[chunk];    // Копировать зашифрованный блок в массив вывода
}
Может это всё можно сделать через sdl?

Цитата Сообщение от castaway Посмотреть сообщение
Если я не ошибаюсь, то округлить вверх можно так: i = (i + 15) / 16 * 16;
Ну тут особо разницы нет, у меня даже поменьше операций(тут ещё умножить на 2 и прибавить 16 нужно добавить будет)...
0
DrOffset
7320 / 4420 / 1001
Регистрация: 30.01.2014
Сообщений: 7,259
07.01.2016, 03:17 #4
Цитата Сообщение от артист Посмотреть сообщение
А так, сколько?
Нисколько.
Указатель - содержит адрес. В твоем случае указатель есть, а значения адреса нет, т.к. не было инициализации.

Цитата Сообщение от артист Посмотреть сообщение
Я уже гуглил, везде указатель, указатель, а что он делает и зачем он, не пишут...
В морской бой играл? В тетрадке в клеточку рисуешь квадрат, разлиновываешь его на строки и столбцы. По горизонтали сверху или снизу пишешь буквы А, Б, В... и т.д. По вертикали цифры 1, 2, 3... и т.д. Итого клетка, которую хочешь побить, определяется однозначно как комбинация горизонтальных и вертикальных обозначений. Это и есть адрес, указатель, если представить, очень грубо, что память - это такой же квадрат, только больше.
Итак, у нас есть строка. Каждый символ занимает одну ячейку в нашей тетрадке. И у нас есть адрес начала этой строки, т.е. указатель на первую клеточку с первым символом строки. Чтобы определить где конец, условились, что после всех символов, которые составляют строку, мы будем ставить ноль (0). Итого, чтобы определить длину строки, нам нужно, используя адрес начала строки, отсчитать то количество ячеек, в которых не встречается ноль. Как только встретили ноль, считаем, что строка кончилась.
1
артист
3 / 5 / 4
Регистрация: 17.09.2014
Сообщений: 710
Завершенные тесты: 1
07.01.2016, 04:43  [ТС] #5
Вот если создавать:

C++
1
byte Data;
byte - тип элемента, в данном случае указывает, что элемент занимает 1 байт (8 бит) памяти.
Сам элемент будет иметь начало в 0A и конец в 0H.
Название: 2.jpg
Просмотров: 46

Размер: 30.1 Кб

Теперь элемент состоит из 2х типов (ячеек) по 8 бит каждая:
C++
1
byte Data[2];
Элемент 0 будет иметь начало в 0A и конец в 0H, элемент 1 - начало 0J конец 1F.
Название: 3.jpg
Просмотров: 46

Размер: 32.6 Кб

А так:
C++
1
byte * Data;
Будет указано только начало в 0A ?
Т.е. элемент не имеет чётко обозначенных границ и типов?
Название: 1.jpg
Просмотров: 48

Размер: 25.9 Кб
0
gru74ik
Модератор
Эксперт CЭксперт С++
4169 / 1817 / 198
Регистрация: 20.02.2013
Сообщений: 4,958
Записей в блоге: 21
07.01.2016, 08:02 #6
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от артист Посмотреть сообщение
А так:
C++
1
byte * Data;
Классический случай - неинициализированный указатель. Указатель, указывающий в никуда.
Обычная переменная хранит в себе значение определённого типа. А указатель в качестве значения хранит адрес.

Можно провести такую аналогию:
Переменная типа House - дом. В доме живут реальные люди (переменная хранит реальные данные). Указатель на переменную House - табличка на доме с написанным на ней адресом "ул. Олега Вещего, дом 4" (значение, которое хранит указатель - это адрес). Неинициализированный указатель - пустая табличка. Компилятор - человек, ищущий адрес по табличкам на домах. Что будет, если табличка указывает в никуда? Будет UB. И как оно проявится в данном отдельно взятом случае никто не знает. Зависит от человека (реализации компилятора). Кто этот человек? Просто прохожий? Почтальон? Торговец гербалайфом? Свидетель Иеговы? Киллер? Террорист, у которого стоит задача подложить мешок с гексогеном по определённому адресу? Врач, спешащий по экстренному вызову?

Или ещё: переменная - дом. Указатель - конверт с адресом. Неинициализированный указатель - письмо без адреса. Компилятор - почтальон. Куда принесёт почту почтальон, если на конверте не написан адрес?
Если Вы не посылали письмо и оно лежит у Вас в конверте без адреса в ящике стола - ничего страшного (объявили указатель на тип T, но не разыменовывали его).
А вот если Вы послали письмо "на деревне дедушке" (попытались разыменовать неинициализированный указатель), то тут UB, т.е. дальнейшие действия зависят от почтальона (компилятора).
Может оставит письмо на почте. Может выкинет в мусорку. Может отправит не тому человеку. А может сойдёт с ума и придёт убивать Вас за неподписанный конверт.
2
артист
3 / 5 / 4
Регистрация: 17.09.2014
Сообщений: 710
Завершенные тесты: 1
09.01.2016, 01:51  [ТС] #7
Всё равно не понял...

Вернее я понял, что когда ставишь звёздочку это адрес памяти.

А что такое разыменование, не инициализированный указатель не понял, и не понятно зачем нужны эти указатели, в каких случаях их применять.
0
avgoor
915 / 550 / 119
Регистрация: 05.12.2015
Сообщений: 1,531
09.01.2016, 14:30 #8
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от артист Посмотреть сообщение
А что такое разыменование, не инициализированный указатель не понял, и не понятно зачем нужны эти указатели, в каких случаях их применять.
Программа - это набор операций с какими-то сущностями. Чтобы оперировать с сущностью надо:
1) Знать ее тип, например, int. Но int – очень сложно, пусть тип будет «лопата». Тип «лопата» - это просто слово, которым мы обозначаем то, чем можно копать, т.е. чтобы копать нам нужна:
2) конкретная лопата (объект класса «лопата» или переменная типа «лопата», если «лопата» - встроенный тип). Например,

«лопата лопата_джамшута=совковая_лопата;».

Здесь мы определили объект «лопата_джамшута» класса «лопата» и инициализировали его значением «совковая лопата».
Теперь мы можем копать. Но иногда нам нужно другое имя для нашей лопаты – это будет ссылка:

«лопата& лопата_равшана=лопата_джамшута;».

Теперь лопата_джамшута и лопата_равшана два разных имени, обозначающих одну и ту же лопату.
Теперь об указателях. Указатель - это новая сущность, в отличие от ссылки. Определим ее:

«лопата *подноситель_лопат=&лопата_джамшута;».

Здесь мы создали указатель на лопату по имени «подноситель_лопат». & в выражении «&лопата_джамшута» - операция взятия адреса, т.е. сказать, где лежит лопата_джамшута. Теперь если подносителю лопат сказать принести лопату – он принесет лопату_джамшута сделать это можно с помощью операции разыменования – «*». Таким образом сделать лопату для насяльника, такую же как у джамшута можно с помощью:

«лопата лопата_насяльника=*подноситель_лопат».

Здесь мы создали новую лопату и инициализировали ее той лопатой, которую принес подноситель лопат.
Т.к. указатель – это сущность, то его можно настроить на другую лопату (в отличие от ссылки): подноситель_лопат++; Теперь он принесет лопату, которая лежит в шкафу после лопаты Джамшута и т.д. (подноситель_лопат[10],….) Но, если его не инициализировать и сказать принести лопату – неизвестно что он принесет и к чему это приведет (например он случайно попробует без спроса принести лопату Виктора Марьяновича, а он наказывает, жестоко наказывает).
1
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.01.2016, 14:30
Привет! Вот еще темы с ответами:

Как пользоваться отладчиком? - C++
Дайте ссылку на хороший материал или литературу

Как пользоваться отладчиком? - C++
Вот код. В книжке написано: &quot;поставьте точку останова Отладчика на оператор j=i и в цикле работы getline() убедитесь, что переменная j...

Dev-C++ Как пользоваться? - C++
Установил Dev-C++. Не могу понять многое в том числе как графический интерфейс создаватью Может кто ссылкой на хороший мануал поделится?

как правильно пользоваться - C++
Здравствуйте, нашел интересный код для интересной задачи (Удалить комментарии из файла), но как сделать так,чтобы программа брала input.txt...


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

Или воспользуйтесь поиском по форуму:
8
Yandex
Объявления
09.01.2016, 14:30
Ответ Создать тему
Опции темы

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