Я профессионально пишу на Java последние 5 лет. Недавно мне пришлось немного покопаться в JNI, чтобы вызвать некоторые специфические для Windows функции.
Этот опыт показал, что я плохо владею языком C (или C++, если на то пошло). Моим единственным введением в C была небольшая книга для "чайников", которую я прочитал в старшей школе 11 лет назад.
Я знаю, что оба языка продвинулись за это время, особенно C++ и стандартная библиотека.
Подходит ли мне изучение C или C++? Какие книги подойдут лучше всего?
Есть ли у людей также какие-либо рекомендации по программированию для Windows? Я могу читать MSDN достаточно хорошо, чтобы понять определенные вызовы API, но у меня такое чувство, что я упускаю что-то в отношении «общей картины».
Спасибо
Оскар: msdn.microsoft.com/en-us/library/aa383749(VS.85).aspx - это та документация, которая вам нужна. Да, внешне он выглядит иначе, чем javadoc, но он такой же подробный и должен рассказать вам все, что вам нужно знать. Кейси, вы хотите изучить C / C++ сами по себе или просто вызывать функции win32?




Я думаю, что Вам будет намного легче овладеть C++, чем C.
Если вы использовали Java, вам было бы трудно отказаться от таких удобств, как классы, исключения, форма ссылок, динамическое связывание и т. д. И, конечно же, достойные библиотеки.
Тем не менее, вы должны сначала выучить C, чтобы убедиться, что вы действительно понимаете, что скрывается под капотом, и можете испытать указатели, их использование и ощущение работы «без защитного снаряжения».
Освоив это, узнайте о механизмах наследования в C++ и о том, чем он отличается от Java (например, множественное наследование).
@Uri, Привет, я уверен, что Джоэл не согласился бы с тобой по поводу изучения C в первую очередь. Нет! (-:
На самом деле я не согласен с тем, что C++ проще. Да, классы есть, но если вы используете их как Java, вы облажались. C++ радикально отличается от Java, и я думаю, что было бы проще просто изучить основы C. Особенно, если цель состоит в простом взаимодействии с Win32, C должно быть достаточно.
Описание OP звучало так, будто он был готов больше заниматься C / C++, чем просто JNI. Если вы привыкли к классам, имитировать их на C бессмысленно. C - отличный язык, но у него есть свои ограничения.
Возможно. Как вы говорите, это зависит от того, чем он хочет заниматься. Для взаимодействия с Win32 C++ - излишний. Но для специальной нативной разработки я бы также предпочел C++.
Я не согласен сначала изучать C, лучше изучу C++ и позже буду искать различия между C++ и C. Если вы не переходите на низкоуровневую платформу или на неподдерживаемую платформу, вам будет бесполезно сначала выучить C. Кроме того, вы избежите изучения вещей на языке C (плохом способе).
Изучать C намного проще, чем C++, у вас нет наследования, шаблонов, ссылок, все, кого вы видите, но я не могу с вами спорить, потому что ваш единственный аргумент заключается в том, что C - плохой путь (что субъективно и личное мнение).
Указатели на функции вместо функторов, коды возврата вместо исключений ... Все это считается плохим. Кроме того, изучение того, что легко сделать с помощью C++, может быть затруднено на C. Я бы не стал изучать потенциально бесполезный язык только потому, что он содержит менее высокоуровневые функции.
Я согласен с вами, что коды возврата, указатели функций и т. д. - это старые вещи, и они намного предпочтительнее, чем пользовательские более современные конструкции для нового кода. Но если вы пишете код на низком уровне (например, win32 api), вы все равно застряли на нем.
Но я не предлагаю вам не изучать C++, я предлагаю начать с C, а затем перейти на C++, который намного лучше подходит для современных проектов, и дать вам что-то действительно мощное, например шаблоны (boost, stl и т. д. ).
Наследование Java имеет, шаблоны и ссылки, поэтому эти концепции должны быть ему понятны. Изучение C++ не должно быть таким уж трудным.
Шаблоны C++ намного сложнее, они содержат множество правил, касающихся разрешения, специализации, и вы можете реализовать наследование во время компиляции.
CShipley: В Java нет шаблонов, и ссылки на нее не совпадают со ссылками на C++. Тот факт, что одинаковые слова существуют на обоих языках, не делает их идентичными.
Это действительно зависит от ваших сильных и слабых сторон. Если вам действительно нравятся шаблоны проектирования, я бы предложил использовать C++, но если вам просто нужно реализовать пару простых методов в JNI, я бы порекомендовал C. Изучение C до C++ должно дать вам лучшее понимание управления памятью, не имея беспокоиться о некоторых сложностях C++ (порядок вызова конструкторов, деструкторы и другие различия между C++ и Java).
Я бы предложил "Язык программирования C" Кернигана и Ричи в качестве исчерпывающего руководства по изучению C. http://www.amazon.com/Programming-Language-Dennis-M-Richie/dp/0876925964
Если вы работаете в системе * nix, на страницах руководства имеется обширная документация по различным функциям. Например,
bash$ man malloc
Шаблоны проектирования на C - это самая большая PITA, с которой можно работать, но это лучшее упражнение из всех.
Если вы хорошо разбираетесь в Java, я бы порекомендовал начать с C, если вы начинаете непосредственно с C++, между ним и Java есть много различий, и он вам, вероятно, не понравится.
Если вы серьезно относитесь к изучению обоих языков, я бы порекомендовал "Язык программирования C++" Бьярна Страуструпа и "Язык программирования C" Денниса Ритчи.
Думаю, это зависит от ваших целей.
Если хотите подойти поближе к машине, то C.
Если вы хотите дополнить свои знания о OO-подобном Java-уровне выше C, тогда C++.
Accelerated C++ (дезинфицированная ссылка Amazon) - отличная книга для изучения C++ с точки зрения C++, а не только C с другими добавленными битами,
И K'n'R C (дезинфицированная ссылка Amazon) - все еще способ изучить C ИМХО!
Кстати, для C++ воспользуйтесь мудростью Скотта Мейерса в книгах «Эффективный C++»! И его книга «Эффективный STL».
HTH
ваше здоровье,
Роб
Рекомендация великого Скотта Мейерса. Я считаю его книги потрясающими. Я никогда не видел книгу «Эффективный STL». К тому времени, как она вышла, я перешел на Java.
Хороший вопрос. На первый взгляд было бы очевидно рекомендовать C++, потому что «он объектно-ориентированный, как Java». Единственная проблема в том, что это не совсем так ... C++ допускает ООП, да, но это всего лишь одна из нескольких парадигм, поддерживаемых C++. Отношение к C++ как к языку ООП (и особенно к нему как к Java) приведет только к разочарованию.
Проблема в том, что между Java и C++ на самом деле не так много общего. Программисты Java часто считают, что Java была вдохновлена C++, но это верно только в том случае, если под C++ вы имеете в виду самые ранние версии C++, которые правильнее было бы назвать «C с классами». С тех пор C++ полностью превратился в собственный язык со своим собственным способом работы. Вероятно, с тех пор он изменился гораздо больше, чем Java. В то время программист на Java все еще был бы в состоянии разобраться в сегодняшнем Java-коде. Не так для C++. Поэтому я бы сказал, что C на самом деле ближе к Java, чем «современный C++». C - это то, что вы получите, если возьмете Java и уберете GC, концепцию классов и несколько других абстракций. Чтобы прийти к C++, вам нужно Добавлять аналогичное количество функций нашей гипотетической урезанной Java.
Кроме того, C++ - чрезвычайно сложный язык, и на его изучение уходит много времени. И если вы не научитесь этому хорошо, вы будете снова и снова стрелять себе в ногу.
Наконец, это зависит от ваших целей. C++ - намного более современный язык, чем C, и как только вы его изучите, он станет очень выразительным и мощным и, что удивительно, может быть даже очень элегантным и лаконичным. Но кривая обучения отвратительна. Так что для нативного программирования в долгосрочной перспективе я бы рекомендовал C++ вместо C.
Но если ваша цель в первую очередь - взаимодействовать с Win32 API (или другим собственным API, если на то пошло), вам не понадобится C++. Win32 и большинство других API написаны на C, а не на C++, и вам, скорее всего, в любом случае не понадобится очень сложный код для взаимодействия между ним и Java.
Насчет изучения Win32, вы правы, все необходимые подробности есть на MSDN. Если вам нужна общая картина, Петцольд - это книга в по этой теме.
Ух ты, предельно лаконичный ответ. +1
Какой из них какой? Я не ОП, я не знаю его целей, поэтому не могу принимать решение за него. Лучшее, что я мог сделать, это описать обстоятельства, при которых каждый язык может быть предпочтительнее.
Выучите достаточно C++, чтобы использовать его в качестве «лучшего C». Вам не нужно пытаться сопоставить все это со своим пониманием Java. Все, что вам нужно, - это иметь возможность использовать объекты C++ в качестве абстрактных типов данных, новых и удаленных и т. д. Если STL придет на помощь, тем лучше.
Настоящий вопрос: почему вы думаете, что JNI является такой абсолютной необходимостью? Вызовы Windows разрушат любую мысль о переносимости вашего приложения. Я сижу рядом с парнем, которому нужно копаться в Java-приложении, использующем JNI. Он случайным образом отключает сервер с ошибкой SEG. Его гипотеза состоит в том, что куча заполняется, JNI вызывает подпрограмму, которая вызывает malloc для выделения места в куче. Он недоступен, процедура не проверяет возвращаемый указатель на нуль, освобождает его, и сервер отключается. Он все еще пытается воспроизвести ошибку локально, потому что для вызова метода JJNI непосредственно перед запуском сборщика мусора требуется точное время.
100% уверены, что они нужны? Просто спрашиваю....
Согласен во многом. Вы действительно хотите избежать худших частей C, таких как написание int foo (); вместо int foo (void) ;.
Если вы намерены продолжать писать код JNI, я определенно рекомендую C++.
В частности, интерфейс JNI требует, чтобы вы получали (и впоследствии выпускали) ссылки на объекты Java. Используя автоматические переменные C++, вы можете получить эти ссылки с помощью методов RAII (Resource Allocation is Initialisation), которые значительно упрощают управление памятью.
Сам интерфейс JNI основан на C. Хотя C++ RAII упрощает управление ресурсами JVM / среды, он определенно скрывает проблему (поскольку объекты Java сильно отличаются от объектов C++).
Я не стал комментировать объекты Java и C. Но я знаю, что некоторые простые оболочки C++ могут значительно упростить код JNI, потому что я это сделал. Как насчет JNIString, который автоматически освобождается при выходе и может автоматически преобразовываться в (char *)?
100% sure they're required? Just asking....
К сожалению, да.
Спасибо всем за ответы.
Чтобы ответить на некоторые последующие вопросы, я не ищу смены карьеры на C или C++. Я просто хотел бы изучить основы, чтобы я не чувствовал себя слепым, когда мне действительно нужно писать отрывки и кусочки.
Если вы хотите заменить свой опыт работы с Java, определенно выберите C. Мне нравится C++, но я думаю, что это в основном язык «только для экспертов». C будет намного более продуктивным для вас как второстепенный (N-арный?) Язык из-за его простоты.
In particular, the JNI interface requires you to acquire (and subsequently release) references to Java objects. Using C++ auto variables you can get these references using 'RAII' (Resource Allocation is Initialisation) techniques which makes memory management far simpler.
Спасибо, это полезно. Одна из областей, которая вызывала у меня растущее беспокойство, заключалась в ручном управлении памятью, связанной с объектами JNI.
Я не знаю JNI, но, вероятно, было бы неплохо взглянуть на boost :: shared_ptr <> (см. boost.org). Это дает вам указатели с подсчетом ссылок, которые автоматически освобождают объекты, если на них больше нет ссылок.
@Kevin - вы уже вынуждены управлять ресурсами в Java - всем, кроме памяти. Это означает открытые файлы, сегменты разделяемой памяти, сетевые соединения и т. д. Если вы сосредоточитесь на общем управлении ресурсами, а не просто на управлении памятью, вы сделаете большой шаг вперед по сравнению с многими разработчиками Java.
Если вам нужен отличный ресурс по C, то книга Денниса Ритчи "Язык программирования C" - это то, что вам нужно.
2-е издание K&R было бы моей рекомендацией. А также книга Гая Стила.
Если ваша «основная цель» здесь - программировать под Windows, я бы рекомендовал C# вместо C или C++. Однако я считаю, что каждый программист на Земле и на более низкой орбите ДОЛЖЕН знать C. Незнание C++ приемлемо, хотя вас могут и не пригласить на несколько вечеринок :) Но C - это что-то вроде обряда перехода между приложениями (высокие- уровень) программист и библиотечный (низкоуровневый) программист.
Интегрируется ли C# напрямую с Java? Я ожидал, что они оба будут интегрированы через C DLL или аналогичный.
Нет, ни в коем случае C# не интегрируется с Java, однако программисту легче перемещаться между ними, и есть даже несколько кросс-компиляторов для простых вещей.
Я нахожусь в какой-то похожей ситуации. Я хотел бы изучить Win32 API, возможно, для улучшения своих приложений Java, когда это необходимо. Но я не нахожу хорошего ресурса для C++ Win32 API. Или, может быть, это только я, и все выглядит совсем не так, как мой старый javadoc :(