Первое, что вы должны понимать, это то, что C и С++ — разные языки, и их смешивание сложно сделать правильно, а часто и плохая идея. Вы, конечно, не хотите писать код «C style» на С++, и многие идиомы С++ невозможны в C.
Ниже приведена рекомендация, специфичная для C, но процесс очень похож на С++.
C не имеет «домашней страницы», как и многие другие языки, поэтому для начинающего может быть немного сложным.
Как упоминается в комментарии pmg, вы должны попытаться получить как можно больше компиляторов. Написание портативных и правильных C или С++ легко ошибиться, и чем больше компиляторов вы проверите свою работу, тем лучше.
Доступно несколько разных компиляторов:
Здесь я перечисляю только те, которые доступны бесплатно, потому что, как новичок, вы, вероятно, не хотите тратить деньги на то, что вам даже не нужно.
MSVC
Microsoft Visual С++ — это компилятор, предлагаемый Microsoft для платформы Windows. Если вы пишете код для Windows, это, вероятно, компилятор, который вы хотите. Пакет MSVC также содержит компилятор C. Экспресс-версия, которая является бесплатной загрузкой, ограничена в некотором смысле (в частности, отсутствием поддержки 64-битной версии), но по-прежнему является очень качественным компилятором. Вероятно, это «простой» вариант, так как загрузка включает в себя все, что вам нужно для разработки.
НКУ
Сборник компилятора GNU (GCC) содержит высококачественные компиляторы C и С++. Он должен быть установлен в большинстве UNIX, а в окнах он доступен в MinGW. Если вы решите, что хотите его использовать, тогда вам нужно рассмотреть несколько различных пакетов, таких как TDM-GCC и STL distro.
IDE
Вероятно, вам также нужна интегрированная среда разработки. Загрузка Microsoft Visual Studio содержит высококачественную среду IDE, которая хорошо интегрирована с MSVC. Если вы используете GCC, я бы рекомендовал Eclipse CDT. Это может занять немного времени, чтобы настроить его, но это также очень качественная среда разработки.
В качестве дополнительной заметки для С++ — кода, скомпилированного с разными компиляторами (и даже разными версиями одного и того же компилятора), вряд ли будет совместимо время ссылки. Это означает, что если вы загружаете «предварительно скомпилированную» библиотеку, вы должны быть очень осторожны, чтобы она была скомпилирована с совместимым компилятором, иначе она просто не сработает.
qaru.site
Имена не имеют типа C. Некоторые типы имен обозначают сущности, имеющие тип, такие как имена typedef, объекты или функции. Другие типы имен обозначают объекты, которые не имеют типа, например символы препроцессора или метки goto
. Однако другие типы имен просто обозначают сами типы, а именно имена typedef
.
Название функции обозначает объект, который имеет тип функции. Этот тип функции включает возвращаемый тип и (возможно, неполную) информацию о параметрах.
Когда функции используются как значения, они всегда обрабатываются как типы указателей. Функция как таковая не может быть передана в переносной программе на C, но указатель на функцию может быть.
Концептуально даже при прямом вызове типа foo()
происходит то, что foo
, выражение, обозначающее функцию, при оценке неявно преобразуется в значение указателя на функцию. После этого оператор postfix оператора ()
вызывает эту функцию с помощью этого указателя.
Существует правило, что выражение, имеющее тип функции, создает значение указателя кроме, если это выражение является операндом &
(адрес) или оператора sizeof
. func
и &func
эквивалентны только в том смысле, что они дают одно и то же значение. func
выводит значение указателя неявно. &func
подавляет неявное генерирование указателя (func
является операндом &
, и поэтому преобразование подавляется), но затем &
принимает адрес.
Итак, вы можете видеть, что sizeof &func
и sizeof func
отличаются. Первый принимает размер указателя, а последний пытается взять размер функции.
Принимая размер функции, это нарушение ограничений в C: для этого требуется диагностика из реализации, которая соответствует стандарту. Если программа все еще переводится, и при запуске создается значение 1
, то есть «бонусное» поведение, характерное для вашей языковой реализации. Это не стандартный язык.
qaru.site
В С++ вы можете написать C-код и успешно скомпилировать его как С++ (в основном). Поэтому, хотя я предлагаю, чтобы ваш термин «беспорядок» был унизительным и неоднозначным, единственным беспорядком, который у вас будет, является то, что вы решили написать себе. Вы можете использовать С++ как большую сумку для инструментов, не используя все инструменты (или беспорядок, если хотите).
Таким образом, ответ — это С++, нравится вам это или нет. Большинство других C-подобных языков добавляют OO-функции, которые, возможно, вы считаете беспорядочными, но вы ничего не получаете ничего, и вам нужно иметь синтаксис для поддержки дополнительных функций. К таким языкам относятся:
Из этих Objective-C, вероятно, наиболее C-Like, так как это надмножество C в том смысле, что С++ не совсем. Это также предпочтительный язык для разработки OSX и iPhone/iPod Touch, который может быть привлекательным.
Java вездесущ, но, вероятно, лучше всего описана как поверхностно C-подобная. С# имеет ограниченную кросс-платформенную поддержку, но это путь наименьшего сопротивления для разработки графического интерфейса Windows с отличными инструментами бесплатной разработки. С# также имеет более простую, но более ограничительную реализацию OO, чем С++, поэтому может соответствовать вашим требованиям, но ее сходство с C/С++ может вводить в заблуждение; он принципиально отличается тем, как он работает аналогично Java. D является чем-то вроде ниши, разработанной одним автором (хотя автор когда-то известного компилятора Zortech/Symantec С++).
Относительно того, что он является «низким уровнем» и «утомительным», когда вы начинаете «крупный проект», вы редко начинаете с нуля, используя только стандартную библиотеку и API-интерфейс ОС, вы должны использовать сторонние и -house разработали библиотеки для быстрого развития функциональности более высокого уровня. Тем не менее, подход OO, как правило, гораздо более поддается этому подходу «повторного использования кода», и, конечно, стандартная библиотека С++ и сторонние библиотеки более обширны (не в последнюю очередь потому, что они могут использовать библиотеки C, а также библиотеки С++). На самом деле я бы посоветовал, что помимо поддержки формы для OO единственное, что делает С++ более высокий уровень, — это расширяемость через классы как объекты первого класса. Тем не менее он по-прежнему подходит как системный уровень.
qaru.site
Число 10000000
(десять миллионов) требует сохранения 24 битов в качестве значения без знака.
Большинство реализаций C не имеют 24-битного типа. Любая реализация, соответствующая стандарту 1999 C или более поздней, должна содержать заголовок <stdint.h>
и должна определять все:
uint_least8_t
uint_least16_t
uint_least32_t
uint_least64_t
каждый из которых является (псевдоним) для целого числа без знака с, по меньшей мере, указанной шириной, так что ни один более узкий целочисленный тип не имеет заданной ширины. Из них uint_least32_t
является самым узким типом, который гарантированно удерживает значение 10000000
.
В подавляющем большинстве реализаций C uint_least32_t
— это тот тип, который вы ищете, но в реализации, поддерживающей 24-битные целые числа, будет более узкий тип, который удовлетворяет вашим требованиям.
Такая реализация, вероятно, определит uint24_t
, предполагая, что 24-битный беззнаковый тип не имеет битов заполнения. Поэтому вы можете сделать что-то вроде этого:
#include <stdint.h>
#ifdef UINT_24_MAX
typedef uint24_t my_type;
#else
typedef uint_least32_t my_type;
#endif
Это все еще не на 100% надежное (например, если есть 28-битный тип, но без 24-битного типа, это пропустит его). В худшем случае он будет выбирать uint_least32_t
.
Если вы хотите ограничить себя предопределенными типами (возможно, потому, что вы хотите поддерживать пре-C99-реализации), вы можете сделать это:
#include <limits.h>
#define TEN_MILLION 10000000
#if UCHAR_MAX >= TEN_MILLION
typedef unsigned char my_type;
#elif USHRT_MAX >= TEN_MILLION
typedef unsigned short my_type;
#elif UINT_MAX >= TEN_MILLION
typedef unsigned int my_type;
#else
typedef unsigned long my_type;
#endif
Если вам нужен только самый узкий предопределенный тип, который гарантированно сохранит значение 10000000
во всех реализациях (даже если некоторые реализации могут иметь более узкий тип, который может его удерживать), используйте long
(int
может быть узким, как 16 бит).
Если вам не требуется использовать целочисленный тип, вы можете просто определить тип, который должен быть 3 байта в ширину:
typedef unsigned char my_type[3];
Но на самом деле это будет шире, чем вам нужно CHAR_BIT > 8
:
typedef unsigned char my_type[24 / CHAR_BIT]
но это не удастся, если 24
не кратно CHAR_BIT
.
Наконец, ваше требование состоит в том, чтобы представить номер 10000000
; вы не сказали, что вам нужно представлять любые другие цифры:
enum my_type { TEN_MILLION };
Или вы можете определить однобитовое битовое поле со значением 1, обозначающим 10000000
и значением 0, обозначающим не 10000000
.
qaru.site
Что острее? Кухонная ложка или кухонный нож?
Чем лучше обрабатывать садовый участок — граблями или лопатой?
Когда вы используете приложение на C# взаимодействующее с операционной системой, то оно вызывает код написанный на С++. Вызовы транслируются к WinAPI, и следовательно никакой код на C# не сможет работать дольше чем на С++.
Исключения есть, и они понятны.
1) в C# нет ассемблера, также как в С++ нет высокоуровневого объектно-ориентированного MSIL. Следовательно в C# вы не напишете код вычисляющий хэш CRC32 в 4-5 строк ассемблерных команд. Вы его напишете на C#, получите около 45 строк на MSIL. И пожалуетесь что тормозит. И верно. Ведь даже на С++ для этого применяют ассемблерную вставку.
2) в C# все сильно стандартизовано. Вы не можете создать ссылку на byte или boolean. И не можете создать ссылку на уничтоженный объект. Пока объект жив ссылка будет существовать. Когда ссылки не будет, то и объект умрет. Плюс это или минус? Нужно ли получать Exception при доступе к не правильной ячейки памяти?
3) в C# выделение памяти происходит при помощи виртуальной машины. А в C++ все вручную. Конечно, если вы бинарные поля упакуете и сделаете из них объекты то всё будет куда компактнее чем аналогичное в C#. Вопрос в том нужно ли вам это. Современные компы имеют от 4 до 8 гигабайтов оперативной памяти. И память продолжает дешеветь. Серверы продают с 32-64 гигами и выше.
о явных преимуществах C#
1) В С++ нет ASP . NET. А это ведущая технология создания веб сайтов. Нет также и WPF, нет silverlight, нет библиотеки 300 мегабайтов.
2) выделение памяти в С# происходит быстрее чем в C++, потому что она обычно упорядочена. При выдаче блока просто выдается следующий блок, а в С++ сперва ищется свободное место.
3) разработка C# быстрее, там и отладка проще, и механизмы выбрасывания исключений упрощены. Нет множественного наследования, нет ссылок на примитивные типы данных, нет проблем с мертвыми ссылками.
итого.
Если у вас целевая аудитория машины с 2 и более гигами памяти то выбирайте C#.
Если вы хотите писать код под процессоры с 8 кб памяти то используйте Си.
Если у вас цель создание GUI — вам в C#.
Если вы делаете только консольные приложения — достаточно и C++.
Если вы сторонник стандартизации и использования готовых программ — вам в C#. Там уже 300 мегабайтов кода.
Если вы сами хотите писать сортировку, искать как реализовать SSL. как сделать HTTP сервер.. . тогда вам в C++.
Кстати, ЕХЕ-шник у C# размерами от 8 кб, а у С++ наверное того меньше. Но С++ не имеет своей библиотеки, в программу придется затолкать тонну библиотек. И ваше простое приложение обязательно будет весить 5 — 40 мб.
Для C# это не реально много. Ведь там есть 300 мб готового кода, который предустановлен на все компьютеры. Сложная программа может занимать 10-20 Кб…
otvet.mail.ru
Я понимаю, что символьная переменная объявляется как char C;
в C. Но какой диапазон значений может содержать переменная символа?
Ответ на самом деле: это зависит от вашей платформы.
К счастью, все это определено в вашей реализации <limits.h>
. Здесь вы найдете константы, которые определяют допустимый диапазон для char
, а также всех других стандартных типов данных.
char
— один байт, который обычно составляет 8 бит. Технически, char
— бит CHAR_BIT
. Для некоторых очень старых машин это было 7, но это были до того, как спецификация C указала, что CHAR_BIT >= 8
. Существуют и другие реализации, такие как DSP, которые имеют более крупные char
.
char
может принимать диапазон CHAR_MIN
в CHAR_MAX
SCHAR_MIN
signed char
может принимать диапазон SCHAR_MIN
в SCHAR_MAX
unsigned char
может принимать диапазон 0
до UCHAR_MAX
CHAR_MIN == SCHAR_MIN
, то ваш char
подписан; в противном случае оно будет неподписанным.Согласно стандарту C (проект N1570):
5.2.4.2.1 Размеры целочисленных типов
Значения, приведенные ниже, должны быть заменены постоянными выражениями, подходящими для использования в директивах #if prefcessing. Кроме того, за исключением CHAR_BIT и MB_LEN_MAX, следующее должно быть заменено выражениями, которые имеют тот же тип, что и выражение, являющееся объектом соответствующего типа, преобразованного в соответствии с целыми рекламными акциями. Их значения, определяемые реализацией, должны быть равны или больше по величине (по абсолютной величине) тем, которые показаны, с тем же знаком.
— количество бит для наименьшего объекта, который не является битовым полем (байтом)
CHAR_BIT 8
— минимальное значение для объекта типа signed char
SCHAR_MIN -127 // −(2^7 − 1)
— максимальное значение для объекта типа signed char
SCHAR_MAX +127 // 2^7 − 1
— максимальное значение для объекта типа unsigned char
UCHAR_MAX 255 // 2^8 − 1
точные значения для вашей реализации можно проверить с помощью значений, определенных в <limits.h>
.
qaru.site
Я не использовал компилятор Microchip, но уже много лет использую продукты HiTech. Мне вообще понравился их компилятор PIC16, но найти их компилятор PIC18 довольно расстраивает. Хотя я считаю, что мне не нужно переносить все переменные в банки, правила, используемые компилятором HiTech, являются раздражающими, причудливыми и тупыми. Краткая история: чип имеет 16 256-байтных банков переменных (* не все 256 байт доступны во всех банках) и один банковский указатель. Прямой доступ к переменной требует, чтобы был выбран правильный банк; изменение банков принимает одну инструкцию.
Глобальные и статические ints и structs и их массивы, размер которых варьируется от 2 до 255 байт, будут распределяться в psect на основе каждого модуля; каждый модуль psect должен соответствовать 256-байтной странице. Массивы байтов, а также отдельные байты идут в «большом» пэде, где предполагается, что каждый байт находится на другой странице.
Все автоматические переменные и параметры во всей программе должны входить в 256-байтовую страницу (они назначаются статически во время соединения). Компилятор делает оверлейные переменные, которые никогда не живут одновременно, но предполагает, что любой вызов указателя функции с конкретной сигнатурой может вызывать любую функцию, адрес которой берется и которая имеет эту подпись.
Можно объявить глобальные и статические переменные размером до 128 байт, которые будут «близки». Доступ к ним возможен без банковского переключения. Невозможно указать, что автоматические переменные или параметры располагаются «рядом».
Правила коммутации банков, используемые HiTech, означают, что многие функции, даже если они никогда не используют какие-либо переменные за пределами их собственного модуля, будут посыпаны инструкциями movlb (switch-bank).
Я не хочу «генерировать всезнающий код». Мне нужна возможность добавить несколько советов, чтобы поместить вещи разумно, определяя ключевые слова или макросы для пользовательских psects, позволяя автоматическим и локальным переменным совместно использовать psect с другими переменными (накладывая автоматические переменные/параметры, насколько это возможно, учитывая указанные банковские ограничения). Если поставщик компилятора действительно хочет быть хорошим, разрешите указателям принимать квалификаторы банков, так что указатель, который будет указывать только на вещи в определенном пэде, может быть сохранен в 8 бит. Аналогичным образом, разрешите квалификаторы банков по функциям и указателям функций указать, что определенные косвенные вызовы могут работать только с определенными функциями. Вместо того, чтобы делать указатели на функции 24 бита или должны работать, чтобы гарантировать, что косвенные функции заканчиваются в первом 64K, установите автоматический GOTO в первые 64K, так что указатели функций могут быть 16-битными. Или еще лучше, если функция ‘class’ имеет менее 64 различных функций, используйте 8-битный указатель.
Я слишком много спрашиваю?
qaru.site