Dmitry Develop
image_2023-12-18_01-46-05.png
Понимание, каким образом хранятся массивы в памяти и как делать одномерную адресацию многомерного массива и наоборот, позволяет некоторые задачи, данные в которых хранятся в виде одномерного массива, представлять, как многомерный массив.
Посмотрите, как выглядел код до и после изменений: это огромная разница.
Эту символьную таблицу, которая представлена одномерным массивом char с null-терминатором в конце, я представил как массив 3 на 3 ячейки и при помощи цикла сделал её заполнение.
Вывод программы (числа для примера только):
Кому не особо понятно, почитайте тут объяснение про массивы и память:
https://t.me/a248640developchat/1029
ссылка на канал | ссылка на группу
Посмотрите, как выглядел код до и после изменений: это огромная разница.
Эту символьную таблицу, которая представлена одномерным массивом char с null-терминатором в конце, я представил как массив 3 на 3 ячейки и при помощи цикла сделал её заполнение.
Вывод программы (числа для примера только):
| sorted | shuffled | unsorted bubble | 1999990 ms | 4999993 ms | 7999996 ms shaker | 2999991 ms | 5999994 ms | 8999997 msselection | 3999992 ms | 6999995 ms | 9999998 msКому не особо понятно, почитайте тут объяснение про массивы и память:
https://t.me/a248640developchat/1029
ссылка на канал | ссылка на группу
👍2
Media is too big
VIEW IN TELEGRAM
Как вам консольное меню?)
Меню многоуровневое с проверкой на корректный ввод.
Весь проект вышел в 700 строк кода.
ссылка на канал | ссылка на группу
Меню многоуровневое с проверкой на корректный ввод.
Весь проект вышел в 700 строк кода.
ссылка на канал | ссылка на группу
🔥2
Dmitry Develop
image_2023-12-20_04-03-51.png
Сегодня я с столкнулся с проблемой правильного отображения строк в кодировке windows-1251 во время отладки в vs code.
Как я понял, vs code корректно отображает строки только в кодировке utf-8, а в моей программе строки закодированы в windows-1251.
На фото в жёлтой рамке сверху в низ: отображение до и после изменений.
Если кодировки по-умолчанию для программы, отладчика и широких строк не подходят, у gdb есть следующие команды:
Устанавливает кодировку, которую использует программа для
Устанавливает кодировку, которую будет использовать gdb во время отладки:
Устанавливает кодировку как для
Устанавливает кодировку, которую использует программа для типов
Выводит текущие используемые кодировки:
Если у команды опустить аргумент с кодировкой, отладчик выведет список поддерживаемых для данной команды.
Если кодировки разные, отладчик попытается преобразовать данные из одной в другую.
В моём случае нужны такие настройки:
Как временное решение эти команды можно вводить в консоли отладки начиная с "
Каждый раз вручную вводить команды неудобно, поэтому лучше их указать в
ссылка на канал | ссылка на группу
Как я понял, vs code корректно отображает строки только в кодировке utf-8, а в моей программе строки закодированы в windows-1251.
На фото в жёлтой рамке сверху в низ: отображение до и после изменений.
Если кодировки по-умолчанию для программы, отладчика и широких строк не подходят, у gdb есть следующие команды:
Устанавливает кодировку, которую использует программа для
char: set target-charset XУстанавливает кодировку, которую будет использовать gdb во время отладки:
set host-charset XУстанавливает кодировку как для
target-charset, так и для host-charset: set charset XУстанавливает кодировку, которую использует программа для типов
wchar_t: set target-wide-charsetВыводит текущие используемые кодировки:
show charsetЕсли у команды опустить аргумент с кодировкой, отладчик выведет список поддерживаемых для данной команды.
Если кодировки разные, отладчик попытается преобразовать данные из одной в другую.
В моём случае нужны такие настройки:
set host-charset UTF-8set target-charset CP1251Как временное решение эти команды можно вводить в консоли отладки начиная с "
-exec ".Каждый раз вручную вводить команды неудобно, поэтому лучше их указать в
launch.json.// launch.json
{
"version": "0.2.0",
"configurations":
[
{
...
"setupCommands":
[
// {
// "text": "set charset UTF-8"
// "ignoreFailures": true
// },
// {
// "text": "set target-wide-charset UTF-16"
// "ignoreFailures": true
// },
{
"text": "set target-charset CP1251"
"ignoreFailures": true
},
{
"text": "set host-charset UTF-8"
"ignoreFailures": true
}
]
...
}
]
}
ссылка на канал | ссылка на группу
Dmitry Develop
ссылка на канал | ссылка на группу
Потихоньку закупаюсь новыми инструментами и радиокомпонентами.
Всё пришло очень быстро).
> Результат выпаивания радиокомпонента полыми трубками
Правда иногда мешает высокая теплоёмкость платы и высокая температура плавления припоя.
Надо бы себе ещё сплав Розе купить.
ссылка на канал | ссылка на группу
Всё пришло очень быстро).
> Результат выпаивания радиокомпонента полыми трубками
Правда иногда мешает высокая теплоёмкость платы и высокая температура плавления припоя.
Надо бы себе ещё сплав Розе купить.
ссылка на канал | ссылка на группу
Есть ли ещё какие-то способы указать желаемую кодировку для строковых литералов?
Кроме:
1) изменения кодировки исходного файла
2) установки ключа
3) использования литералов вида (только для пункта 1 или конкретных стандартов кодирования unicode):
https://en.cppreference.com/w/cpp/language/string_literal
На ум приходят варианты: загрузка строк в нужной кодировке из файла; делать массив char и инициализировать его числовыми кодами конечной кодировки, преобразовывать текст из конечной кодировки в кодировку исходного файла и вставлять его в строковой литерал (скорее всего не будет работать).
Единственный способ, который я нашёл не без подсказки в документации, это сделать строку вручную в виде массива codepoint'ов или строкового литерала с
В С++23 ещё добавят управляющие последовательности вида
https://en.cppreference.com/w/cpp/language/escape
Вне зависимости от кодировки исходного файла, закодированные таким образом строки остаются в своей кодировке без преобразования.
ссылка на канал | ссылка на группу
Кроме:
1) изменения кодировки исходного файла
2) установки ключа
-fexec-charset=X,3) использования литералов вида (только для пункта 1 или конкретных стандартов кодирования unicode):
"char current encoding",L"wide char current encoding",u8"utf-8 encoding",u"utf-16 encoding",U"utf-32 encoding".https://en.cppreference.com/w/cpp/language/string_literal
На ум приходят варианты: загрузка строк в нужной кодировке из файла; делать массив char и инициализировать его числовыми кодами конечной кодировки, преобразовывать текст из конечной кодировки в кодировку исходного файла и вставлять его в строковой литерал (скорее всего не будет работать).
Единственный способ, который я нашёл не без подсказки в документации, это сделать строку вручную в виде массива codepoint'ов или строкового литерала с
\xn....В С++23 ещё добавят управляющие последовательности вида
\x{n...} для строковых литералов в кодировке utf-8, -16 и -32.https://en.cppreference.com/w/cpp/language/escape
// "Кириллица" in utf-8
uint8_t utf8Dec[] { 208, 154, 208, 184, 209, 128, 208, 184, 208, 187, 208, 187, 208, 184, 209, 134, 208, 176, 0 };
uint8_t utf8Hex[] { "\xd0\x9a\xd0\xb8\xd1\x80\xd0\xb8\xd0\xbb\xd0\xbb\xd0\xb8\xd1\x86\xd0\xb0" };
// "Кириллица" in windows-1251
uint8_t cp1251Dec[] { 202, 232, 240, 232, 235, 235, 232, 246, 224, 0 };
uint8_t cp1251Hex[] { "\xca\xe8\xf0\xe8\xeb\xeb\xe8\xf6\xe0" };
Вне зависимости от кодировки исходного файла, закодированные таким образом строки остаются в своей кодировке без преобразования.
ссылка на канал | ссылка на группу
Кто-нибудь знает, можно ли указать gcc в какой кодировке выводить предупреждения и ошибки и как это сделать?
При перенаправлении потока ошибок (
Но если не перенаправлять поток ошибок (
Изменение кодировки консоли на 866, 1251 и 65001(utf-8) до вызова g++ не помогло.
[update]
После некоторых тестов я думаю, что gcc не виноват — он просто выводит текст ошибок в кодировке исходного файла.
А вот консоль windows non ASCII символы в кодировке utf-8 почему-то не выводит.
Но при перенаправлении вывода
В online компиляторе, который на linux работает, всё выводится корректно.
Видимо, проблема в консоли или windows с кодировкой utf-8.
[update]
Да и этот код работает на вывод как utf-8, так и utf-16:
ссылка на канал | ссылка на группу
При перенаправлении потока ошибок (
stderr) в txt файл, при открытии его в кодировке utf-8, содержимое строковых литералов отображается верно: три латинских символа и три кириллических символа: "abcАБВ".> g++ ... charset/main.cpp 2> output.txt
output.txt:
charset/main.cpp: In function 'int main()':
charset/main.cpp:18:20: warning: unused variable 'utf8' [-Wunused-variable]
18 | const uint8_t* utf8 { (const uint8_t *)u8"abcАБВ" };
| ^~~~
charset/main.cpp:19:21: warning: unused variable 'utf16' [-Wunused-variable]
19 | const uint16_t* utf16 { (const uint16_t*) u"abcАБВ" };
| ^~~~~
charset/main.cpp:20:21: warning: unused variable 'utf32' [-Wunused-variable]
20 | const uint32_t* utf32 { (const uint32_t*) U"abcАБВ" };
| ^~~~~
Но если не перенаправлять поток ошибок (
stderr) в файл, сообщение об ошибке выведется в консоль, но, как это обычно бывает, при отличии кодировки текста и консоли, текст усекается: вместо "abcАБВ" выводится только ASCII часть "abc.Изменение кодировки консоли на 866, 1251 и 65001(utf-8) до вызова g++ не помогло.
> g++ ... charset/main.cpp
charset/main.cpp: In function 'int main()':
charset/main.cpp:18:20: warning: unused variable 'utf8' [-Wunused-variable]
18 | const uint8_t* utf8 { (const uint8_t *)u8"abc;
| ^~~~
charset/main.cpp:19:21: warning: unused variable 'utf16' [-Wunused-variable]
19 | const uint16_t* utf16 { (const uint16_t*) u"abc;
| ^~~~~
charset/main.cpp:20:21: warning: unused variable 'utf32' [-Wunused-variable]
20 | const uint32_t* utf32 { (const uint32_t*) U"abc;
| ^~~~~
[update]
После некоторых тестов я думаю, что gcc не виноват — он просто выводит текст ошибок в кодировке исходного файла.
А вот консоль windows non ASCII символы в кодировке utf-8 почему-то не выводит.
Но при перенаправлении вывода
stderr в файл, там появляется правильный текст в кодировке utf-8.В online компиляторе, который на linux работает, всё выводится корректно.
Видимо, проблема в консоли или windows с кодировкой utf-8.
[update]
Да и этот код работает на вывод как utf-8, так и utf-16:
size_t wcslen(const char16_t* wstr)
{
return wcslen((const wchar_t*)wstr);
}
SetConsoleCP(CP_UTF8);
SetConsoleOutputCP(CP_UTF8);
HANDLE consoleOutput { GetStdHandle(STD_OUTPUT_HANDLE) };
const char* newline { u8"\n" };
const char* utf8 { u8R"("XYZ ЭЮЯ")" };
const char16_t* utf16 { uR"("XYZ ЭЮЯ")" };
WriteConsoleA(consoleOutput, utf8 , strlen(utf8) , nullptr, nullptr);
WriteConsoleA(consoleOutput, newline, strlen(newline), nullptr, nullptr);
WriteConsoleW(consoleOutput, utf16 , wcslen(utf16) , nullptr, nullptr);
WriteConsoleA(consoleOutput, newline, strlen(newline), nullptr, nullptr);
// > "./charset/main.exe"
// "XYZ ЭЮЯ"
// "XYZ ЭЮЯ"
ссылка на канал | ссылка на группу
👍1🤡1
Dmitry Develop
newMonitor.jpg
Я несколько лет сидел за очень маленьким монитором (на самом деле это был телевизор).
Разрешение у него было 1024x768 и соотношение сторон 4:3, растянутое до 16:9.
Цветопередача, углы обзора и частота обновления были ужасными.
И вот спустя столько времени я наконец-то купил себе нормальный монитор.
Разрешение 1920x1080, настоящее соотношение сторон 16:9, диагональ 27 дюймов, частота обновления 144 Hz.
Это не монитор, а плазма какая-то: он очень огромный, фильмы и youtube смотреть одно удовольствие.
Большая частота обновления уже позволила мне заметить, что анимации в windows 10, оказывается, очень плавные.
Теперь на экране помещается всё, не надо больше тесниться, очень много свободного места.
ссылка на канал | ссылка на группу
Разрешение у него было 1024x768 и соотношение сторон 4:3, растянутое до 16:9.
Цветопередача, углы обзора и частота обновления были ужасными.
И вот спустя столько времени я наконец-то купил себе нормальный монитор.
Разрешение 1920x1080, настоящее соотношение сторон 16:9, диагональ 27 дюймов, частота обновления 144 Hz.
Это не монитор, а плазма какая-то: он очень огромный, фильмы и youtube смотреть одно удовольствие.
Большая частота обновления уже позволила мне заметить, что анимации в windows 10, оказывается, очень плавные.
Теперь на экране помещается всё, не надо больше тесниться, очень много свободного места.
ссылка на канал | ссылка на группу
👍4
Dmitry Develop
cppinsights.png
На фото: слева исходный вид кода, справа после обработки на сайте.
Добавил новую ссылку в полезные ссылки для C++ разработчиков:
https://cppinsights.io/
На cppinsights можно увидеть, во что превращается ваш код, показывает все неявные моменты и раскрывает синтаксический сахар.
Есть выбор стандарта языка С++, настройки для отображения кода и не только.
ссылка на канал | ссылка на группу
Добавил новую ссылку в полезные ссылки для C++ разработчиков:
https://cppinsights.io/
На cppinsights можно увидеть, во что превращается ваш код, показывает все неявные моменты и раскрывает синтаксический сахар.
Есть выбор стандарта языка С++, настройки для отображения кода и не только.
ссылка на канал | ссылка на группу
👍1
Я хочу поздравить всех с наступающим или уже наступившим новым годом!
Желаю вам успехов, здоровья, счастья и всего наилучшего!
За 2023 год я создал этот канал, познакомился со многими интересными людьми как с России, так и из-за рубежа, устроился наконец-то на работу программистом).
ссылка на канал | ссылка на группу
Желаю вам успехов, здоровья, счастья и всего наилучшего!
За 2023 год я создал этот канал, познакомился со многими интересными людьми как с России, так и из-за рубежа, устроился наконец-то на работу программистом).
ссылка на канал | ссылка на группу
❤6🔥4🎄1
Dmitry Develop
IMG_20240102_060220.jpg
Хорошо, когда дарят нужную и полезную вещь).
Теперь детали не будут храниться то в спичечных коробках, то в коробочках).
ссылка на канал | ссылка на группу
Теперь детали не будут храниться то в спичечных коробках, то в коробочках).
ссылка на канал | ссылка на группу
Dmitry Develop
ссылка на канал | ссылка на группу
Мой велосипед (реализация динамического массива) работает).
Делать его в Си стиле и через
Используя шаблоны можно написать более удобный и эффективный код, добавить перегрузку операторов, и способ использования никак не будет отличаться от статических массивов.
Только вместо
ссылка на канал | ссылка на группу
Делать его в Си стиле и через
void*, мне кажется, это плохая идея хотя бы потому, что это небезопасно и нет статической проверки типов.Используя шаблоны можно написать более удобный и эффективный код, добавить перегрузку операторов, и способ использования никак не будет отличаться от статических массивов.
Только вместо
push_back, как у std::vector, можно перегрузить оператор +=.dynamicArray<int> array { };
// array += 9901;
// array += 9902;
// array += 9903;
// array += 9904;
// array += 9905;
// array += 9906;
// array += 9907;
// array += 9908;
const int elementCount { 8 };
for(int i { }; i < elementCount; ++i)
array += 9901 + i;ссылка на канал | ссылка на группу
Dmitry Develop
image_2024-01-21_06-43-31.png
Продолжаю улучшать свой велосипед.
Было очень неудобно каждый раз явно приводить внутренний указатель к нужному типу:
У меня массив и псевдоним для типа через
Из-за этого и без того некороткая конструкция превращается в ещё более длинную:
И такую длинную конструкцию приходилось писать на каждую запись или чтение.
Первым решением было создать переменную с автовыведением типа и инициализировать его преобразованным к нужному типу данных указателем:
Без ключевого слова auto длина инструкии была бы в два раза больше.
Отлично, теперь для чтения и записи можно использовать обычный синтаксис, как для статических массивов:
Однако, это всё будет работать до первого увеличения размера массива, так как указатель станет просто висячим (невалидным).
Вторым решением было использовать ссылку, но для таких махинаций она не работает, поэтому пришлось делать указатель на указатель, чтобы не хранить копию адреса, а получать всегда актуальный адрес из
Но тогда
Последнее и самое удачное решение, по моему мнению, было разделить управление динамической памятью и информацию о типе данных.
При создании массива указывается адрес переменной array (
ссылка на канал | ссылка на группу
Было очень неудобно каждый раз явно приводить внутренний указатель к нужному типу:
((Type*)dynamicArray.memory)[index].member.У меня массив и псевдоним для типа через
using лежали в структуре, которая приходила в функцию по указателю.Из-за этого и без того некороткая конструкция превращается в ещё более длинную:
((myStruct::Type*)myStruct->dynamicArray.memory)[index].member.И такую длинную конструкцию приходилось писать на каждую запись или чтение.
Первым решением было создать переменную с автовыведением типа и инициализировать его преобразованным к нужному типу данных указателем:
auto array { (myStruct::Type*)myStruct->dynamicArray.memory };.Без ключевого слова auto длина инструкии была бы в два раза больше.
Отлично, теперь для чтения и записи можно использовать обычный синтаксис, как для статических массивов:
array[0].member.Однако, это всё будет работать до первого увеличения размера массива, так как указатель станет просто висячим (невалидным).
Вторым решением было использовать ссылку, но для таких махинаций она не работает, поэтому пришлось делать указатель на указатель, чтобы не хранить копию адреса, а получать всегда актуальный адрес из
dynamicArray:auto array { (myStruct::Type**)&myStruct->dynamicArray.memory };.Но тогда
array[0].member превратится в (*array[0]).member или в array[0][0].member, что вообще выглядит ужасно и непонятно.Последнее и самое удачное решение, по моему мнению, было разделить управление динамической памятью и информацию о типе данных.
dynamicArray отвечает только за динамическую память, а компилятор за всё остальное, что касается типа данных и адресации:dynamicArray arrayMemory { };
Type* array { };`
dynamicArrayAdd(&arrayMemory);
array[0].member = 10;
dynamicArrayAdd(&arrayMemory);
array[1].member = 20;При создании массива указывается адрес переменной array (
void**) для доступа к памяти с информацией о типе данных, и когда старый указатель становится невалидным, dynamicArray после выделения памяти записывает в неё новый валидный адрес.ссылка на канал | ссылка на группу