Re[3]: Hello, World!
От: AlexGin Беларусь  
Дата: 29.06.10 11:02
Оценка:
Здравствуйте, Deeman, Вы писали:


AG>>Любой язык высокого уровня имеет свой набор библиотек.

AG>>Если рассматривать С++, то это библиотеки стандартных функций ввода-вывода, библиотеки строковых и математических функций, наконец библиотека шаблонов STL.

D>Вот я и пытаюсь понять, как они устроены и могу ли я сам написать определение функции printf() в своей программе.


А что конкретно тебе даст "велосипед" под названием printf?

Этот велосипед можно реализовать миллионом разных способов...
Все из них будут работать, будут иметь свои достоинства и недостатки...

Не проще ли сделать что-то свое из примерно того же рода: например даны Фамилия Имя Отчество человека (возможно введены даже всеми строчными или всеми заглавными буквами), написать функцию которая:
1) Сделает первые буквы заглавными, остальные строчные
2) Сформирует инициалы — пример:
на входе: иванов иван иванович (или: ИВАНОВ ИВАН ИВАНОВИЧ)
на выход: Иванов И.И.

Вот простой пример обработки строк — но пример не тривиальный (как printf)
Re[9]: Hello, World!
От: AlexGin Беларусь  
Дата: 29.06.10 11:10
Оценка:
Здравствуйте, LuciferSaratov, Вы писали:

LS>Здравствуйте, AlexGin, Вы писали:


AG>>Все ЯВУ — языки высокого уровня — предполагают облегчение труда программиста, за счет АБСТРАКЦИЙ.

AG>>Эти абстракции сделаны, чтобы помочь программисту сконцентрировать внимание НА ВЫПОЛНЯЕМОЙ ЗАДАЧЕ и на поиске оптимального решения ЗАДАЧ ПОЛЬЗОВАТЕЛЯ/ЗАКАЗЧИКА, а не не том, КАКОВА РЕАЛИЗАЦИЯ рутинных функций компьютера/стандартной библиотеки и т.д.[...]

LS>Это не означает, что никому не нужно знать, как реализованы функции стандартной библиотеки. Я, к примеру, сейчас работаю над проектом на С++, в котором активно используются классы, шаблоны — в общем, многие из высокоуровневых фич языка. Но при этом в этом проекте нельзя пользоваться стандартной библиотекой С и С++, да и само предназначение проекта весьма низкоуровневое. И тут как раз очень нужны знания об устройстве стандартных библиотек С и С++, о том, как реализуется их функциональность, и о том, как программный код взаимодействует с ОС.


Sorry, может я не понял ситуации у топик-стартера, но ИМХО у меня сложилось мнение, что человек просто немного не представляет основного назначения таких объектно-ориентированных языков как C++.

З.Ы. В то же время Вы не станете утверждать, что Ваш случай (в указанном выше проекте) — это пример типового программирования на C++. Это скорее редкое исключение из правил.
Re[8]: Hello, World!
От: Deeman  
Дата: 29.06.10 11:18
Оценка: 1 (1)
AlexGin, Вы писали:

AG>мы имеем черный ящик


Я хочу знать, как работает чёрный ящик. Я не собираюсь писать его заново, я хочу знать, как он работает, потому что чёрный цвет меня пугает. Это, знаете ли, психологическое — если перед тобой неизвестность, ты её боишься. А известность тебя мотивирует.

Поэтому, наверное, мало кто интересуется тем, как же на самом деле всё устроено. Зачем забивать себе мозг?
Re[9]: Hello, World!
От: K13 http://akvis.com
Дата: 29.06.10 12:52
Оценка:
D>Я хочу знать, как работает чёрный ящик. Я не собираюсь писать его заново, я хочу знать, как он работает, потому что чёрный цвет меня пугает. Это, знаете ли, психологическое — если перед тобой неизвестность, ты её боишься. А известность тебя мотивирует.

D>Поэтому, наверное, мало кто интересуется тем, как же на самом деле всё устроено. Зачем забивать себе мозг?


А устройство процессора представляете? Сумматора? Блока умножения? Как работает доступ к памяти — с диаграммами сигналов по ножкам проца?

Когда-то я это знал (для 8086) — но в программировании ценность этой информации == 0.

"Как устроена printf" — это любознательность. "Все вручную" -- это глупость.
Re[2]: Hello, World!
От: Аноним  
Дата: 29.06.10 13:41
Оценка:
Здравствуйте, LuciferSaratov, Вы писали:

LS>
LS>typedef unsigned int HANDLE;
LS>typedef unsigned int DWORD;
LS>typedef DWORD *LPDWORD;
LS>typedef unsigned int BOOL;
LS>typedef void VOID;
LS>typedef VOID *LPVOID;
LS>#define WINAPI __stdcall
LS>#define NULL (0)
LS>#define STD_OUTPUT_HANDLE ((DWORD)-11)

LS>__declspec(dllimport) HANDLE WINAPI GetStdHandle(DWORD nStdHandle);
LS>__declspec(dllimport) BOOL WINAPI WriteConsoleA(HANDLE hConsoleOutput, const VOID *lpBuffer, DWORD nNumberOfCharsToWrite,
LS>                                               LPDWORD lpNumberOfCharsWritten, LPVOID lpReserved);

LS>int main(int argc, char *argv) {
LS>    DWORD dwWritten;
LS>    char msg[] = "Hello, World!";
LS>    WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), &msg[0], sizeof(msg), &dwWritten, NULL);
LS>    return 0;
LS>}
LS>


Тут используется куча статических либ для инициализации CRT и пр.
Для чистоты эксперимента нужно указать линкеру точку входа.
Re[10]: Hello, World!
От: Deeman  
Дата: 29.06.10 13:46
Оценка:
K13, Вы писали:

K13>"Как устроена printf" — это любознательность. "Все вручную" -- это глупость.


Я любознателен, но ручную рутину не люблю.))

LuciferSaratov, Вы писали:

LS>Если стоит задача не использовать никаких библиотек, в том числе библиотек импорта, то фактически задача сведется к получению интерфейса к ОС.


LuciferSaratov, скажите, если мне захочется почерпнуть побольше информации о таком стиле программирования, то что бы вы порекомендовали почитать?
Re[3]: Hello, World!
От: Vamp Россия  
Дата: 29.06.10 20:20
Оценка: +1
D>Спасибо! Становится немного понятнее и уже интереснее.))
А что понятнее-то? Заменили один черный ящик — printf — на другой — WriteConsoleA. Сделали програму сложнее, непортируемую, и без каких бы то ни было улучшений.
Да здравствует мыло душистое и веревка пушистая.
Re[11]: Hello, World!
От: K13 http://akvis.com
Дата: 30.06.10 04:47
Оценка:
D>LuciferSaratov, скажите, если мне захочется почерпнуть побольше информации о таком стиле программирования, то что бы вы порекомендовали почитать?

взять большой листок бумаги и сто раз карандашиком написать "лучше так не делать, а писать простой код используя стандартные функции".
потом стереть ластиком и повторять до просветления.

ситуации, где нельзя пользоваться стандартным рантаймом -- экзотика.
Re[9]: Hello, World!
От: Тот кто сидит в пруду Россия  
Дата: 30.06.10 04:55
Оценка: 1 (1)
Здравствуйте, Deeman, Вы писали:

D>Я хочу знать, как работает чёрный ящик. Я не собираюсь писать его заново, я хочу знать, как он работает, потому что чёрный цвет меня пугает. Это, знаете ли, психологическое — если перед тобой неизвестность, ты её боишься. А известность тебя мотивирует.


Отладчиком зайди да посмотри, делов-то. Да и всяко полезней будет, чем свой принтф писать.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[3]: Hello, World!
От: LuciferSaratov Россия  
Дата: 30.06.10 05:51
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Тут используется куча статических либ для инициализации CRT и пр.

А>Для чистоты эксперимента нужно указать линкеру точку входа.

По заявкам радиослушателей вот исправленный вариант:
typedef unsigned int HANDLE;
typedef unsigned int DWORD;
typedef unsigned int UINT;
typedef DWORD *LPDWORD;
typedef unsigned int BOOL;
typedef void VOID;
typedef VOID *LPVOID;
#define WINAPI __stdcall
#define NULL (0)
#define STD_OUTPUT_HANDLE ((DWORD)-11)

__declspec(dllimport) HANDLE WINAPI GetStdHandle(DWORD nStdHandle);
__declspec(dllimport) BOOL WINAPI WriteConsoleA(HANDLE hConsoleOutput, const VOID *lpBuffer, DWORD nNumberOfCharsToWrite,
                                                LPDWORD lpNumberOfCharsWritten, LPVOID lpReserved);
__declspec(dllimport) VOID WINAPI ExitProcess(UINT uExitCode);

void myentry(void) {
    DWORD dwWritten;
    char msg[] = "Hello, World!";
    WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), &msg[0], sizeof(msg)-1, &dwWritten, NULL);
    ExitProcess(0);
}


В настройках компилятора нужно отключить опцию Buffer security check (/GS), а то линковаться не будет.
Re[11]: Hello, World!
От: LuciferSaratov Россия  
Дата: 30.06.10 06:11
Оценка: 2 (1)
Здравствуйте, Deeman, Вы писали:

D>LuciferSaratov, скажите, если мне захочется почерпнуть побольше информации о таком стиле программирования, то что бы вы порекомендовали почитать?


Это не стиль программирования, это просто бывает нужно в некоторых достаточно редких случаях. Если можно избежать написания кода в таком стиле, то так и следует поступать.
А почитать — ну, к примеру, Джефри Рихтер, Windows для профессионалов.

И вот еще — на этом форуме используется древовидная структура сообщений, поэтому в одном сообщении нужно отвечать одному собеседнику. Так здесь принято, всем понятно и у каждого будет возможность заметить твой ответ. Я вот не с сразу заметил, мог и не ответить.
Re: Hello, World!
От: dcb-BanDos Россия  
Дата: 30.06.10 08:42
Оценка:
Здравствуйте, Deeman, Вы писали:

D>Существует ли решение? В какую сторону искать? Как, чёрт побери, конкретно работает функция printf()?


отладчик отменили?
зайди внутрь printf под отладкой и посмотри, как реализован printf(CRT) в поставке твоего компилятора, если используется MSVC 2005, то по дефолту смотри "C:\Program Files\Microsoft Visual Studio 8\VC\crt\src\"
Ничто не ограничивает полет мысли программиста так, как компилятор.
Re[11]: Hello, World!
От: saf_e  
Дата: 30.06.10 10:49
Оценка:
Здравствуйте, Deeman, Вы писали:

D>K13, Вы писали:


K13>>"Как устроена printf" — это любознательность. "Все вручную" -- это глупость.


D>Я любознателен, но ручную рутину не люблю.))


D>LuciferSaratov, Вы писали:


LS>>Если стоит задача не использовать никаких библиотек, в том числе библиотек импорта, то фактически задача сведется к получению интерфейса к ОС.


D>LuciferSaratov, скажите, если мне захочется почерпнуть побольше информации о таком стиле программирования, то что бы вы порекомендовали почитать?


Скажите, а вас не смущает, что вы не знаете как работают системные АПИ? КАК происходит вывод символов из программной памяти на экран монитора? То, что в данном примере происходит неявное линкование на kernell32.dll (и более того, любая виндоус программа неявно линкуется с ntdll.dll). Вас не пугает, что компилятор+линкер из "простого и понятно" С-кода соберет машинный код и поклеит в файл с секциями напихав его "волшебными значениями", о которых вы и не подозреваете? А система когда запустит образ будет делать с ним еще более противоестественные вещи? Вы тоже хотите сделать это сами?

Знать что происходит (в частности как работает printf) это одно, а писать на самом низком из возможных уровней это другое. Вся история программирования состоит в уходе на все более высокоуровневые конструкции (ASM — C — C++ — ну и т.д.), на каком уровне остановиться решать вам, но использование готовых конструкций/библиотек сильно облегчит жизнь. А понимать надо, да...
Re[4]: Hello, World!
От: Deeman  
Дата: 30.06.10 18:18
Оценка:
Здравствуйте, Vamp, Вы писали:

D>>Спасибо! Становится немного понятнее и уже интереснее.))

V>А что понятнее-то? Заменили один черный ящик — printf — на другой — WriteConsoleA. Сделали програму сложнее, непортируемую, и без каких бы то ни было улучшений.

Не совсем "заменили". На мой взгляд, printf и WriteConsoleA — два совершенно разных понятия, поскольку WriteConsoleA — это прямое обращение к операционной системе, а printf — опосредованное.

Но я нигде не говорил, что так лучше. Вопрос стоял "как это работает", а не "как сделать лучше".
Re[5]: Hello, World!
От: Ops Россия  
Дата: 30.06.10 18:23
Оценка: :)
Здравствуйте, Deeman, Вы писали:

D>Не совсем "заменили". На мой взгляд, printf и WriteConsoleA — два совершенно разных понятия, поскольку WriteConsoleA — это прямое обращение к операционной системе, а printf — опосредованное.


Вы не поверите, но WriteConsoleA — тоже опосредованное, это обертка над WriteConsoleW
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re[6]: Hello, World!
От: Ops Россия  
Дата: 30.06.10 18:29
Оценка:
Причем, вполне вероятно, что лет через 5-10 MS нагло удалит WriteConsoleA из WINAPI (если раньше вендекапец не случится), а вот printf будет работать.
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re[12]: Hello, World!
От: Deeman  
Дата: 30.06.10 18:36
Оценка:
Здравствуйте, K13, Вы писали:

D>>LuciferSaratov, скажите, если мне захочется почерпнуть побольше информации о таком стиле программирования, то что бы вы порекомендовали почитать?


K13>взять большой листок бумаги и сто раз карандашиком написать "лучше так не делать, а писать простой код используя стандартные функции".

K13>потом стереть ластиком и повторять до просветления.

По-моему, это беда всех форумов. Я вот модератор, правда, на форуме музыкальном. И иногда приходят люди и спрашивают — а как устроена музыка, почему в натуральных ладах семь нот, откуда беруться искажения в ухе? И вот про новичка все думают — о, он считает, что познав искажения в ухе он начнёт писать хорошую музыку! Конечно не начнёт. И есть новички, которые это прекрасно понимают, но тем не менее хотят знать суть вещей. А сопротивление форума лишь мешает достижению этой цели, "отцы" ставят новичков "на место", убивая в них всякое разумное стремление к познанию чёрных ящиков (мол, не трогай, всё испортишь!), в результате чего произростает глупость, лень и неверные представления об мироздании.

И поэтому, пока у меня есть силы, желание и мозг мой не столь стар, я хочу знать, какие это такие поршня вертятся в двигателе моего автомобиля, зачем они нужны и как их делают. А на права каждый дурачок может сдать, как показывает практика.
Re[12]: Hello, World!
От: Deeman  
Дата: 30.06.10 18:37
Оценка:
Здравствуйте, LuciferSaratov, Вы писали:

LS>Это не стиль программирования, это просто бывает нужно в некоторых достаточно редких случаях. Если можно избежать написания кода в таком стиле, то так и следует поступать.

LS>А почитать — ну, к примеру, Джефри Рихтер, Windows для профессионалов.

Спасибо. Книжка эта, оказывается, у меня есть.
Re[6]: Hello, World!
От: Deeman  
Дата: 30.06.10 18:40
Оценка:
Ops, Вы писали:

Ops>Вы не поверите, но WriteConsoleA — тоже опосредованное, это обертка над WriteConsoleW


Поверю, отчего ж.))
Re[3]: Hello, World!
От: Vamp Россия  
Дата: 30.06.10 18:47
Оценка:
D>Спасибо! Становится немного понятнее и уже интереснее.))
Ок. Тебе понятнее.
Тогда вот тебе вопрос для размышления.

howthisworks.exe > file

Эта команда запустит howthisworks.exe и, в случае использования print, вместо консоли сохранит текст в файл file.
Вопрос:
1. При использовании WriteConsoleA это поведение сохранится?
2. Объясни, почему.

Интереснее?
Да здравствует мыло душистое и веревка пушистая.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.