Что такое пример, в котором знание C заставит меня написать лучший код на каком-либо другом языке?

Я отправляю ответ на свой вопрос здесь после его решения, поэтому, если у других возникнет та же проблема, они смогут найти простое решение здесь.

Как вы можете видеть выше, командная строка компилятора nvcc.exe не редактируется, потому что это просто функция различных других редактируемых свойств.

Тем не менее, единственная причина, по которой я хотел отредактировать командную строку nvcc, была в первую очередь из-за следующей ошибки компилятора:

1> nvcc fatal: для несвязанного требуется один входной файл фаза, когда указан выходной файл

Компилятор NVidia CUDA nvcc.exe работал правильно для моей сборки отладки Visual Studio, но каждый раз приводил к ошибке с вышеуказанной ошибкой для любой сборки выпуска.

Я ожидал, что для решения этой проблемы мне придется отредактировать командную строку nvcc.exe, однако это оказалось не так по следующей причине.

Когда я удалил все пробелы в именах сборок конфигурации Visual Studio, проблема полностью исчезла!

Очевидно, компилятор nvcc.exe не может обрабатывать пробелы в именах сборок конфигурации, несмотря на использование двойных кавычек вокруг них во всех ссылки на командную строку. Следовательно, эта проблема, вероятно, является чем-то внутренним для компилятора nvcc и никогда не была обнаружена NVidia просто потому, что большинство людей достаточно умны, чтобы не использовать пробелы в именах своих сборок.

В итоге, не используйте пробелы в именах сборок конфигурации VS, и у вас не будет этой проблемы с компилятором NVidia CUDA.

15
задан Eric Ryan Harrison 6 April 2009 в 12:47
поделиться

20 ответов

Классический пример, который использует Joel Spolsky, находится на неправильном употреблении strcat и strlen и определения "Shlemiel живописец" алгоритмы в целом.

Не то, чтобы Вам нужен C для решения проблем, которые не могут решить высокоуровневые языки, случается так, что знание C хорошо дает Вам взгляд на то, что продолжается под всеми теми уровнями языков, который позволяет Вам писать лучшее программное обеспечение. Поскольку просто такая перспектива помогает Вам избежать написания кода, которое является, неизвестно Вам, на самом деле O (n^2), например.

Править: Некоторое разъяснение на основе комментариев.

Знание C не является предпосылкой для такого знания, существует много способов получить то же знание.

Знание C является также не гарантией этих навыков. Можно быть опытными в C и все же все еще написать ужасный, безобразный, топорный код на любом языке, которого Вы касаетесь.

C является низкоуровневым языком, все же он все еще имеет современные управляющие структуры и функции, таким образом, Вы не всегда становитесь оказавшимися в трудных деталях. Очень трудно стать опытным в C, не получая мастерство определенных основных принципов (таких как детали управления памятью и указателей), мастерство которого часто выплачивает богатые дивиденды при работе на любом языке.

Это всегда об основных принципах.

Это верно во многом преследовании, а также разработке программного обеспечения. Это не секретные заклинания, которые делают лучших программистов лучшим, скорее это - большее мастерство основных принципов. Опыт показал, что знание C имеет тенденцию иметь более высокую корреляцию к мастерству определенных из тех основных принципов, и что изучение C имеет тенденцию быть одним из более легких и более общих маршрутов к получению такого знания.

23
ответ дан 1 December 2019 в 00:30
поделиться

Знание C является большим, потому что оно ничего не делает за Вашей спиной (GC, проверка границ, и т.д.). Это только делает точно, что Вы говорите этому также. Ничто не подразумевается. Даже C++ делает вещи, которые Вы не говорите ему также с RAII (конечно, подразумевается, что объект разрушен, когда он выходит из объема, но Вы на самом деле не пишете это). C является отличным способом изучить то, что продолжается 'под капотом' компьютера, не имея необходимость писать блок.

0
ответ дан 1 December 2019 в 00:30
поделиться

неэффективный код (например, циклы string+=) обычно неэффективны на любом языке. какое значение это имеет, если кто-то объясняет, почему это неэффективно на одном языке или другом? знание C, но не понимание, что метод неэффективен, не отличается, чем знание Python и не понимание того же.

0
ответ дан 1 December 2019 в 00:30
поделиться

В Python скажите, что у Вас есть функция

def foo(l=[])
  l.append("bar")
  return l;

На некоторой версии Python, доступного приблизительно год назад, рабочее нечто () в течение многих времен, Вы получили бы действительно интересный результат (т.е. ["bar","bar","bar","bar]).

Кажется, что кто-то реализовал параметры по умолчанию как статическую переменную (и не сбрасывая его), таким образом, неожиданные результаты происходят.

Возможно, мой пример был изобретен - мой друг, которому на самом деле нравится Python, найденный этой специфической ошибкой, но факт вопроса является всеми этими языками, реализованы в C или C++. Знание и не понимание понятий, которые фундаментальны для основного языка, означают, что у Вас не будет всестороннего понимания языков, которые создаются вдобавок ко всему

Я нахожу весь "почему беспокойство с вопросом о C/C ++/ASM глупый". Если Вы склонны достаточно для изучения языка, который означает, что Вам достаточно любопытно войти в него первое место. Почему остановка в незадолго до C?

0
ответ дан 1 December 2019 в 00:30
поделиться

Я не думаю, что может быть любой определенный пример.

То, что изучение C делает для Вас, дают Вам понимание, расширение ума, в то, как работают компьютеры (и программное обеспечение). Это - очень абстрактная вещь..

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

Ссылка, что Wedge сделал к упоминанию статьи Joel Shlemiel живописцем, является интересной, но не имеет никакой уместности здесь. Тот алгоритм не связывается с C никаким конкретным способом (хотя он проявляется в завершенных пустым указателем строках).

Строки Python неизменны так или иначе и полностью отличаются от модели C строк, таким образом, я не вполне вижу отношений.

Я предполагаю, что один конкретный пример оптимизирует синтаксический анализатор или лексический анализатор или программу, которая продолжает писать в строковый буфер все время. При использовании нормальных строк вместо строкового буфера Вы будете натыкаться на проблему при создании очень больших строк.

Полагайте что:

a = a + b 

делает копию из обоих a и b. Это не меняет струну, на которую сослался a, это создает новую строку, выделяя больше памяти, и т.д.

Если a значительно становится большим, и Вы продолжаете добавлять мелочи к нему, затем Shlemiel, который живописец проявит сам.

Но с другой стороны, знание это не имеет никакого отношения к знанию C, просто зная, как Ваш язык реализует вещи на низком уровне. (Это - то, где наличие experiece в C поможет Вам).

0
ответ дан 1 December 2019 в 00:30
поделиться

Технически, все дефициты C вынудили бы Вас кодировать вокруг них; то, чтобы заставлять Вас написать больше кода-> создание Вас более опытный в целом. Испытывая недостаток в любом портативном целом числе, больше, чем 32 бита, например, C имеет, в прошлом заставил меня записать свою собственную библиотеку сверхбольшого числа.

Отсутствие неявной памяти, управления ресурсами и управления обработкой ошибок (сборка "мусора", RAII, названный конструкторами/деструкторами, возможно, исключения), вынуждает пользователей C записать большую инициализацию, обработку ошибок и код очистки. Это могу просто быть я, но я никогда не устал от написания такого кода. Я иду и читаю документацию каждой внешней функции, которую я вызываю, возвращаю своему коду и проверке на каждое возвращаемое значение и другой показательный отказом материал. Это даже заставляет меня чувствовать себя в безопасности!

Эта последняя точка является, вероятно, самой большой, которая будет сделана в пользу аргумента. Можно только записать столько malloc () / свободный () пары, прежде чем Вы начнете анализировать время жизни каждой переменной, с которой Вы сталкиваетесь на каждом языке! Объекты автоматического хранения C++ не помогают этому разупорядочению, также.

Написание действительно портативного кода C часто требует, чтобы программист, чтобы быть свободным от большого количества предположений о хост-системе - думал sizeof (), CHAR ___ БИТЫ, неподписанные длинный, UINT_MAX. В то время как это не помогло мне написать лучший код на других языках, он помог мне думать о возможных альтернативных реализациях: как крошечный микропроцессор мог все еще выполнить мой код C, генерировав огромное количество инструкций RISC для моего простого короткого оператора. (Который является другой вещью; не много других языков отображаются на и от данного ассемблера так легко в моей голове. С другой стороны это может просто быть я.)

Конечно, ни один из этих аргументов не идет только для C. @S.Lott имеет актуальный вопрос - Фортран мог бы быть одинаково хорошей альтернативой. Но вокруг существует так много кода C! Целая система персонального компьютера сверху донизу - приложения к библиотекам к драйверам к ядру - доступна в исходном коде в C. Это была бы пустая трата, если Вы не могли бы считать его.

0
ответ дан 1 December 2019 в 00:30
поделиться

Не зная Perl хорошо, я задаюсь вопросом, возможно ли теперь распределить загрузку процессора больше чем в одно физическое ядро с несколькими потоками, созданными в единственной программе в Perl, не порождая дополнительные процессы

0
ответ дан 1 December 2019 в 00:30
поделиться

Знание C не является требованием к способности эффективно использовать высокоуровневые языки, но, конечно, может помочь общее понимание того, как компьютеры и работа программного обеспечения - я думаю, что это подобно утверждению, что знание некоторого ассемблера или архитектуры ЭВМ / аппаратная логика (and/or/nand логические элементы, и т.д.) может помочь программисту C быть лучшим программистом.

Иногда для решения проблемы, она помогает знать, как вещи работают 'внизу', что Вы делаете.

Я не думаю, что это означает, что программист должен знать C, чтобы быть хорошим программистом, но я думаю, что знание C может быть полезно почти любому программисту.

0
ответ дан 1 December 2019 в 00:30
поделиться

Вы не можете записать ядро ОС в Perl; C был бы намного лучшим выбором для этого, потому что это - достаточно низкий уровень для выражения всего, что ядро должно сделать, и достаточно портативный, чтобы позволить Вам портировать свое ядро на различную архитектуру

0
ответ дан 1 December 2019 в 00:30
поделиться

Я думаю, что стоит знать некоторый язык низкого уровня, и есть прагматичные причины для выбора C:

  • Это низкий уровень, близкий к ассемблеру
  • Это широко распространено

Понимание всего стека является ценным. Иногда вам нужно что-то отладить. Иногда вы не можете исправить проблему производительности без знания низкого уровня (это часто не случай, например, когда проблема производительности является чисто алгоритмической, но иногда это так).

Почему C широко считается квинтэссенцией «дна стека», а не какого-либо другого языка (языков)? Я думаю это потому, что C - это язык программирования низкого уровня, и C победили . Это было какое-то время, но C не всегда был таким доминирующим. Возьмем лишь один известный пример: сторонники Common Lisp (у которого были свои способы написания низкоуровневого кода) надеялись, что их язык тоже будет популярен, и в итоге потеряли .

Следующее обычно реализуются в операционных системах C:

  • (варианты Unix, Windows, многие встроенные операционные системы)
  • языки программирования более высокого уровня (многие популярные реализации Java, Python и т. д.)
  • (очевидно) множество популярных проекты с открытым исходным кодом

Я не специалист по аппаратным средствам, но я понимаю, что C также сильно повлиял на дизайн процессора.

Так что, если вы верите в понимание всего стека, изучение C с прагматической точки зрения лучший выбор.

Как предостережение, я думаю, что стоит также изучить ассемблер. Хотя С близко к металлу, я не Я не до конца понимаю C, пока мне не понадобится ассемблер. Иногда полезно понять, как фактически выполняются вызовы функций, как реализованы циклы для циклов и т. Д. Менее важным, но также полезным является (хотя бы один раз) иметь дело с системой без виртуальной памяти. При использовании C в Windows, Unix и некоторых других операционных системах даже скромный malloc выполняет большую часть работы под прикрытием, которую легче оценить, отладить и / или настроить, если вам когда-либо приходилось иметь дело с ручной блокировкой и разблокировкой областей памяти (не то, чтобы я рекомендовал делать это регулярно!)

приходится (хотя бы один раз) иметь дело с системой без виртуальной памяти. При использовании C в Windows, Unix и некоторых других операционных системах даже скромный malloc выполняет большую часть работы под прикрытием, которую легче оценить, отладить и / или настроить, если вам когда-либо приходилось иметь дело с ручной блокировкой и разблокировкой областей памяти (не то, чтобы я рекомендовал делать это регулярно!)

приходится (хотя бы один раз) иметь дело с системой без виртуальной памяти. При использовании C в Windows, Unix и некоторых других операционных системах даже скромный malloc выполняет большую часть работы под прикрытием, которую легче оценить, отладить и / или настроить, если вам когда-либо приходилось иметь дело с ручной блокировкой и разблокировкой областей памяти (не то, чтобы я рекомендовал делать это регулярно!)

0
ответ дан 1 December 2019 в 00:30
поделиться

Я вижу его как это, все сводится к C на межплатформенном уровне и блоку в особенном методе платформы. Таким образом, это похоже на то, чтобы быть гонщиком Ралли по пересеченной местности, и C является базовой автомобильной механикой, можно быть большим драйвером, но когда Вы попадаете в беду, зная C, означает, что можно, вероятно, вернуть себя в гонке, если не Вы застреваете, называя механику. И блок - то, что знают механика и производители, это - достойные инвестиции, если это - то, что Вы хотите сделать, иначе можно просто доверять механике.

Поскольку специфические особенности думают об управлении памятью, hardwar драйверы, механизмы физики, высокопроизводительная 3-я графика, стопки TCP, протоколы двоичной синхронной передачи данных, встроенное программное обеспечение, создавая высокоуровневые языки как Perl

0
ответ дан 1 December 2019 в 00:30
поделиться

Вы используете, выстраивает много? и Вы сталкиваетесь с ситуациями, где Вам нужны объекты, которые будут сохранены в памяти, не зная сколько из них (т.е. на основе запроса от базы данных?) затем я предполагаю, что C преподавал бы Вам большие вещи как стеки, структуры и списки ссылок, которые могли бы помочь Вам. С уважением, Andy

1
ответ дан 1 December 2019 в 00:30
поделиться

Как кто-то, кто знает немного C, но любит писать код в жемчуге и других высокоуровневых языках, я никогда не сталкивался с проблемой, которую я смог решить путем записи C.

Я ищу примеры реальных ситуаций, где знание C было бы полезно при записи проекта на языке высокого уровня/динамичном как жемчуг или Python.

Легко начать писать код высокого уровня, и затем задаваться вопросом мы это отстает. Истина существует много способов записать жемчуг или код Python, и некоторые лучше (как в более эффективном), чем другие. Если Вы знаете низкоуровневые детали того, как Ваш код выполнен в жемчуге или Python (оба из которых записаны в C) можно кодировать вокруг нескольких неэффективности - как знание, какая конструкция цикличного выполнения быстрее, как память сохраняется/выпускается и т.д.

Кроме того, при записи проекта в жемчуге или Python Вы иногда врезаетесь в стену производительности. Создатели языка (Guido, по крайней мере) защитник, что Вы реализуете ту часть в C как расширение языка. Чтобы сделать это, ну, в общем, необходимо будет знать C.

Так, там.

2
ответ дан 1 December 2019 в 00:30
поделиться

Знание C помогает Вам написать лучший код в C. Я предполагаю, что пример Joel Spolsky мало полезен в C++ или Objective C, где определенные классы для управления строками существуют и были обработаны с производительностью в памяти. Кроме того, использование C приемы на других языках может быть продуктивным прижиганием.

Тем не менее, C знание очень полезно для понимания общих понятий на других языках и что находится позади капота во многих ситуациях.

2
ответ дан 1 December 2019 в 00:30
поделиться

В целях аргумента предположите, что Вы хотели связать строковые представления всех целых чисел от 1 до n (например, n = 5 произведет строку "12345"). Вот то, как можно было бы сделать это наивно в, скажем, Java.

String result = "";
for (int i = 1; i <= n; i++) {
    result = result + Integer.toString(i);
}

Если бы необходимо было переписать тот сегмент кода (который довольно красив в Java) в C максимально буквально, то Вы заставили бы что-то заставлять большинство программистов C съежиться в страхе:

char *result = malloc(1);
*result = '\0';
for (int i = 1; i <=  n; i++) {
    char *intStr = malloc(11);
    itoa(i, intStr, 10);
    char *tempStr = malloc(/* some large size */);
    strcpy(tempStr, result);
    strcat(tempStr, intStr);
    free(result);
    free(intStr);
    result = tempStr;
}

Поскольку строки в Java неизменны, Integer.toString создает фиктивную конкатенацию строк, и конкатенация строк создает новый строковый экземпляр вместо того, чтобы изменить старый. Это не легко видеть от просто рассмотрения кода Java. Знание, как упомянутый код переводит в C, является одним способом изучить точно, как неэффективный упомянутый код.

2
ответ дан 1 December 2019 в 00:30
поделиться

Классическими примерами являются вещи, включающие более низкое управление памятью уровня, такие как реализация класса связанного списка:

struct Node
{
    Data *data;
    Node *next;
}

Понимание, как указатели используются для итерации списка, и что они показывают с точки зрения архитектуры машины, позволит Вам лучше понимать свой код высокого уровня.

Другим примером, к которому обращался Joel, была реализация конкатенации строк и правильный способ создать строку из ряда данных.

// this is efficient
for (int i=0; i< n; i++)
{
    strcat(str, data(i));
}

// this could be too, but you'd need to look at the implementation to be sure
std::string str;
for (int i=0; i<n; i++)
{
  str+=data(i);
}
2
ответ дан 1 December 2019 в 00:30
поделиться

Приводить Вам определенную причину: необходимость записать мои собственные стандартные программы Сборки "мусора" помогла моей записи лучше кодировать.

Я не думаю, что когда-либо находил проблему, которую я не смог решить с высокоуровневым языком; но запустился путем изучения C, это привило мне множество превосходных методов разработки. Знание, как элементарные части потока работы приложения включат Вам смочь посмотреть на Ваш собственный код и получить пользу, визуальную из того, как потоки данных, и где это хранится. Это затем приводит к лучшему, понимают того, как разыскать просачивающуюся память, медленное чтение с диска, плохо созданные кэши, и т.д.

Отслеживание Указателей..., это - другой, который приходит на ум.

3
ответ дан 1 December 2019 в 00:30
поделиться

Трудно определить количество точно, но наличие понимания C даст Ваше больше понимания, как реализованы высокоуровневые конструкции языка, и как следствие Вы будете лучше способны использовать конструкции интеллектуальным способом.

3
ответ дан 1 December 2019 в 00:30
поделиться

Это - ошибка предположить, что изучение C так или иначе автоматически даст Вам лучшее понимание проблем низкоуровневого программирования. В большом количестве случаев даже C является слишком высоким уровнем, чтобы дать Вам хорошее понимание проблем эффективности.

Классик - я ++ по сравнению с ++ я. Это сверхцитируется, поэтому возможно, большинство людей знает последствия о производительности между этими двумя операциями. Но изучение C волшебно не преподавало бы Вам это отдельно.

Я предполагаю, что понимаю аргументы о строках. Когда строковые операции сделаны обманчиво простыми, люди часто используют их неэффективными способами. Но снова, знание, что strncat существует, не дает Вам полную оценку для проблем эффективности. Много программистов C, вероятно, даже не думало о том, что strncat должен сделать strlen операцию внутренне.

Даже с помощью C, важно понять то, что продолжается негласно, если эффективность является беспокойством. Люди, которые знают C, склонны просматривать вещи в прогрессии. Ассемблерный код и машинный код являются стандартными блоками C, в то время как C является стандартным блоком высокоуровневых языков.

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

Таким образом, Вы хотите определенный пример того, как знание C дает Вам преимущество. Я не думаю, что существует тот. Я думаю, что имеют в виду люди, когда они говорят, что это - то, что знание, что продолжается негласно на любом языке, для которого Вы, оказывается, пишете, помогает Вам принять более интеллектуальные решения относительно того, как написать код. Однако это - ошибка предположить, что C, "что продолжается негласно" в Java, например.

8
ответ дан 1 December 2019 в 00:30
поделиться

Знание C действительно не стоит очень. Многим из нас, кто знает C глубоко, нравится думать, что все это глубокое понимание ценно и важно.

Некоторые из нас, кто знает C, не могут думать о единственной определенной функции C, о котором это полезно для знания.

Знание, как работа указателей в C (особенно с синтаксисом C) не является всем этим полезным. На высокоуровневом языке Ваши операторы создают объекты и управляют их взаимодействием. Указатели и ссылки - возможно - интересны с гипотетической точки зрения. Но знание не оказывает практического влияния на то, как Вы используете Java или Python.

Высокоуровневые языки являются способом, которым они. Знание, как не изменяет те языки; это не изменяется, как Вы используете их, отлаживаете или тестируете их.

Знание, как создать или управлять связанным списком, не оказывает земного влияния на определение класса списка Python.Ничего.

Знание различия между Связанным списком и Списком массива могло бы помочь Вам записать программу Java. Но реализация C не помогает Вам выбрать между Связанным списком и Списком массива. Решение независимо от знания C.

Плохой алгоритм плох на каждом языке. Знание внутренних тайн C не делает плохой алгоритм немного менее плохим. Знание C не помогает Вам знать наборы Java или Python встроенные типы.

Я не вижу значения в изучении C. Изучение Фортрана так же ценно.

1
ответ дан 1 December 2019 в 00:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: