Какие важные понятия в Си, которые вы не узнали от своих учителей? [закрыто]

«Цель OPN [Отладка] отменяет настройку сборки OTHER_LDFLAGS». Это был главный вопрос. После добавления $ (унаследованного) в новой строке в других флагах компоновщика решена моя проблема.

25
задан 6 revs, 4 users 57% 6 September 2017 в 17:22
поделиться

55 ответов

Описание компоновщика. Любой, кто использует C, должен понимать, почему "static int x;" в области видимости файла не создает глобальную переменную. Упражнение по написанию простой программы, где каждая функция находится в своей собственной единице трансляции и компилируется каждая отдельно, выполняется недостаточно часто на ранних этапах изучения C.

8
ответ дан 28 November 2019 в 17:33
поделиться

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

  • Этапы предварительного планирования и немного о том, как искать существующий проект / существующий код, который вы можете использовать, чтобы уменьшить количество исходного кода
  • Небольшой (базовый) обзор лицензий и то, как этот внешний код влияет на то, какие лицензии вы используете может и не может использовать (и другие соображения, которые относятся к лицензированию)
  • Одновременное управление версиями и управление версиями. Я бы сделал SVN / Git, но каждому свое. Вы сэкономите им СТОЛЬКО времени, если познакомите их сейчас, а не будете учиться на работе.
2
ответ дан 28 November 2019 в 17:33
поделиться
  • Хлебная память может вызвать самые разные странные ошибки.
  • Отладчики могут вам лгать.
6
ответ дан 28 November 2019 в 17:33
поделиться

Я думаю, что общая идея кажется действительно хорошей. Это еще кое-что.

  1. Отладчик - хороший друг.
  2. Проверьте границы.
  3. Убедитесь, что указатель установлен на самом деле указывая на что-то перед его использованием.
  4. Управление памятью.
5
ответ дан 28 November 2019 в 17:33
поделиться

Надеюсь, этого раньше не публиковали (просто прочтите очень быстро), но я думаю, что очень важно, когда вам нужно работать с C, - это знать о машинном представлении данных. Например: числа с плавающей запятой IEEE 754, обратный порядок байтов от старшего к младшему, выравнивание структур (здесь: Windows против Linux) ... Чтобы попрактиковаться в этом, очень полезно составить несколько бит-головоломок (решение некоторых проблем без использования каких-либо функций, а затем printf для печати результата, ограниченное количество переменных и некоторые логические операторы). Также часто бывает полезно иметь базовые знания о том, как работает компоновщик, как работает весь процесс компиляции и т. Д. Но особенно разбираться в компоновщике (без этого так сложно найти какие-то ошибки ...)

Книга, которая больше всего помогла мне улучшить мои навыки C и C ++, была: http://www.amazon.com/Computer-Systems-Programmers-Randal-Bryant/dp/013034074X

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

5
ответ дан 28 November 2019 в 17:33
поделиться

Как насчет общих передовых практик?

  • Всегда предполагайте, что кто-то уже написал ваш код, и что это одновременно свободно доступны в Интернете и лучше написаны и протестированы, чем все, что вы производить до наступления крайнего срока.
  • Возврат раньше / Избегать предложений else
  • Инициализировать все переменные
  • По одной странице на функцию в качестве ориентира (т.е. использовать вместе меньшие фрагменты кода)
  • Когда использовать переключатель, if-else if или хеш-таблица
  • Избегайте глобальных переменных
  • Всегда проверяйте свои входы и выходы (я не доверяю своему собственному коду.)
  • Большинство функций должны возвращать статус

    [Другим: не стесняйтесь редактировать это и добавлять в список]

Относительно проверки входных данных:

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

Думайте о предохранительных предложениях как о предупреждениях и ошибках компилятора во время выполнения.

5
ответ дан 28 November 2019 в 17:33
поделиться

Это ключевое слово в C: volatile ََََ

4
ответ дан 28 November 2019 в 17:33
поделиться
  • Где язык заканчивается и начинается реализация: например, stdio.h является частью стандартной библиотеки, conio.h - нет, и тому подобное;
  • Разница между undefined и реализацией -определенное поведение, и почему такие вещи, как x = x ++, не определены;
  • Просто потому, что он компилируется, не значит, что он правильный;
  • Разница между приоритетом и порядком оценки, и почему a * b + c не гарантировать, что a будет оцениваться до b или c;
  • «Он работает на моей машине» не превосходит поведение, указанное в языковом стандарте: например, только потому, что void main () или x = x ++ дает ожидаемые результаты для конкретной платформы и компилятора не означает, что его можно использовать
  • Представьте, что вы никогда не слышали о gets ();
3
ответ дан 28 November 2019 в 17:33
поделиться

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

2
ответ дан 28 November 2019 в 17:33
поделиться
  • Непроцедурные методы программирования, включая шаблоны ООП в C.
  • Расширенные методы препроцессора C
  • Отладка с помощью чего-то другого, кроме printf ().
  • Функции компоновщика и компоновщика, включая сборку общие / динамические объекты.
  • Модульное тестирование и фиктивные объекты, TDD в целом.
2
ответ дан 28 November 2019 в 17:33
поделиться

Было бы полезно, если бы учащиеся в какой-то момент познакомились с инструментами, которые могут помочь им писать чище, лучший код. Не все инструменты могут иметь отношение к ним на данном этапе, но знание того, что доступно, помогает.

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

  • Показатели кода - CCCC , Понять , SLOCCount , ...
  • Покрытие кода - gcov, LCOV, ...
  • Один Следует также подчеркнуть использование разных (!) компиляторов со строгими флагами предупреждений компилятора и внимания к каждому предупреждающему сообщению.

  • Показатели кода - CCCC , Понять , SLOCCount , ...
  • Покрытие кода - gcov, LCOV, ...
  • Один Следует также подчеркнуть использование разных (!) компиляторов со строгими флагами предупреждений компилятора и внимания к каждому предупреждающему сообщению.

    2
    ответ дан 28 November 2019 в 17:33
    поделиться

    Заключите все параметры макроса в круглые скобки.

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

    #define M(A) do { ... (A) ... } while (0)
    
    1
    ответ дан 28 November 2019 в 17:33
    поделиться

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

    ПРИМЕЧАНИЕ: Я не сказал игнорировать компилятор. Я сказал, не верь этому. Он знает, что есть проблема, но часто ошибается в том, что именно. Принимать выходные данные компилятора за чистую монету - это рецепт разочарования и траты времени. Особенно для сложных ошибок.

    1
    ответ дан 28 November 2019 в 17:33
    поделиться

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

    if (islower(letter)) {
       pos = letter - 'a' + 1;
    } else if (isupper(letter)) {
       pos = letter - 'A' + 1;
    }
    

    vs:

    pos = letter & 31;
    

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

    - мои 2 цента

    1
    ответ дан 28 November 2019 в 17:33
    поделиться
    • Использование отладчиков и других инструментов анализа (таких как Valgrind и т. Д.)
    • Уловки оптимизации, такие как устройство Даффа.

    Я очень рад сказать, что меня учили почти всему остальному, что здесь уже упоминалось (включая модульное тестирование и шаблоны ООП в C, правда!).

    1
    ответ дан 28 November 2019 в 17:33
    поделиться

    #pragma , может использоваться для передачи дополнительной информации процессору. Я работал над процессорами TI с языком C, и это очень помогло мне в определении сегментов памяти.

    Также '__ FILE__' и '__LINE__' предопределенные макросы очень полезны при отладке / ведении журналов, но я никогда этого не знал. Такие вещи нужно рассказывать студентам.

    1
    ответ дан 28 November 2019 в 17:33
    поделиться

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

    a= 1, b= 2;
    

    Конечно, вы используете его внутри операторов for (;;) {}, но никто никогда не понимал почему, и я никогда не видел, чтобы кто-то еще использовал это, кроме операторов for.

    Но C обрабатывает запятые иначе, чем точки с запятой. Например:

    "if (a) b = a, c = a;"
    

    то же самое, что

    "if (a) { b = a; c= a; }"
    

    , но отличается от

    "if (a) b = a; c = a;
    

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

    Кроме того, я обнаружил, что если у меня есть много инициализации в верхней части функции,

    a = 1,
    b = 2,
    i1 = 0,
    i2 = 0,
    i3 = 0,
    i4 = 0,
    dtmp = 0.0,
    p = strtmp;
    

    Разделение всех этих назначений запятыми делает их одним оператором и позволяет мне «пройти» в отладчике все из них за один шаг вместо восьми (или более). Да, современные графические интерфейсы делают установку точки останова и переход между ними менее болезненными, но одно действие (шаг) по-прежнему трудно превзойти.

    1
    ответ дан 28 November 2019 в 17:33
    поделиться

    Компилятор не всегда прав. Особенно при разработке для встраиваемых систем.

    0
    ответ дан 28 November 2019 в 17:33
    поделиться

    Концепции порядка выполнения и точек последовательности довольно полезны и мало обсуждаются.

    Полезно знать, что x = x ++; вызывает неопределенное поведение. Знание , почему это может быть намного более познавательным.

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

    0
    ответ дан 28 November 2019 в 17:33
    поделиться

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

    0
    ответ дан 28 November 2019 в 17:33
    поделиться

    Моделирование объектов с помощью структур и указателей функций

    0
    ответ дан 28 November 2019 в 17:33
    поделиться
    • Никто никогда меня не учил выкладывать проект. На таком языке, как C, часто бывают файлы заголовков, код файлы, библиотеки для статических и динамических связывание и т. д. Что входит в заголовок и что входит в код файл? Если все это просто застрянет в один каталог или следует они каким-то образом сгруппированы?
    • Если они будут использовать Visual Studio, это делается для того, чтобы никогда не узнать, как использовать компилятор, и в чем разница между компиляцией и компоновкой.
    • Обучите их, как использовать сборку инструмент как сделать, а также почему.
    1
    ответ дан 28 November 2019 в 17:33
    поделиться

    Хорошие концепции переносимого кодирования, модели программирования (например, ILP32 по сравнению с LP64) и предоставление их различным компиляторам C и инструментальным средствам (не во всем мире используется GCC).

    0
    ответ дан 28 November 2019 в 17:33
    поделиться

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

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

    1
    ответ дан 28 November 2019 в 17:33
    поделиться
    if(constant=variable)
    {
    work();
    }
    
    0
    ответ дан 28 November 2019 в 17:33
    поделиться
    Другие вопросы по тегам:

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