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

В подкастах Stack Overflow Джоэл Спольски постоянно говорит Джеффу Этвуду о том, что Джефф не знает, как писать код на C. Его утверждение таково: «Знание C помогает вам писать лучший код». Он также всегда использует какую-то историю, связанную с манипулированием строками, и то, как знание C позволит вам писать более эффективные строковые процедуры на другом языке.

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

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

Редактировать: Чтение некоторых ответов, которые вы, ребята, представили, было великолепным, но все равно не имеет для меня никакого смысла в этом отношении:

Возьмите пример с strcat. Есть правильный и неправильный способ комбинировать строки в C. Но почему я (как разработчик высокого уровня) должен думать, что я умнее Ларри Уолла? Почему бы разработчикам языка не написать правильный код для работы со строками?

Ответы [ 20 ]

23 голосов
/ 06 апреля 2009

Классический пример, который использует Джоэл Спольски, - это неправильное использование strcat и strlen и определение алгоритмов «Шлемиэль, художник» в целом.

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

Редактировать: Некоторые пояснения, основанные на комментариях.

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

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

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

Это всегда об основах.

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

8 голосов
/ 06 апреля 2009

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

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

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

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

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

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

3 голосов
/ 06 апреля 2009

Чтобы дать вам конкретную причину: необходимость писать собственные процедуры сборки мусора помогла мне написать лучший код.

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

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

3 голосов
/ 06 апреля 2009

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

2 голосов
/ 07 апреля 2009

Для целей аргумента предположим, что вы хотите объединить строковые представления всех целых чисел от 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 голосов
/ 06 апреля 2009

Знание C помогает вам писать лучший код на C. Я предполагаю, что пример Джоэла Спольски мало пригоден в C ++ или Objective-C, где существуют специальные классы для работы со строками, которые были разработаны с учетом производительности. Более того, использование трюков на С в других языках может быть более продуктивным.

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

2 голосов
/ 06 апреля 2009

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

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

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

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

// 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 голосов
/ 07 апреля 2009

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

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

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

Кроме того, при написании проекта на Perl или Python вы иногда попадаете в стену производительности. Создатели языка (по крайней мере, Гвидо) рекомендуют вам реализовать эту часть в C как расширение языка. Для этого вам нужно знать C.

Итак, там.

1 голос
/ 06 апреля 2009

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

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

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

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

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

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

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

Я не вижу никакой ценности в изучении C. Изучение Фортрана столь же ценно.

1 голос
/ 06 апреля 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...