Ответы пользователя по тегу C
  • Есть ли в Си функция, читающая TCP без коллбеков?

    CityCat4
    @CityCat4 Куратор тега C
    //COPY01 EXEC PGM=IEBGENER
    В С вообще есть любая функция :) Какую напишете :)

    Есть socket(). Есть connect(). Есть bind(). Есть listen(). Есть read(). Есть accept(). Вот на них обычно и строится все.
    Ответ написан
    Комментировать
  • Передача массива в функцию?

    CityCat4
    @CityCat4 Куратор тега C
    //COPY01 EXEC PGM=IEBGENER
    Передача массива по значению - неэффективна. Я вот не могу вспомнить ни одного случая, когда это реально было нужно. Обычно передают по ссылке. Иногда еще передают количество элементов, иногда закладывают лишний элемент-ограничитель, который маркирует конец массива.
    Ответ написан
  • Нужно ли вообще очищать память в этом месте?

    CityCat4
    @CityCat4 Куратор тега C
    //COPY01 EXEC PGM=IEBGENER
    Программа крашится потому что неосторожное обращение с памятью способно разломать таблицу выделенных участков, в результате чего при попытке освободить память будет происходить фигня. Внимательно погоняйте программу отладчиком и посмотрите - не выходит ли у вас *_string за допустимые пределы.
    Ответ написан
    Комментировать
  • Как записать данные в переменную?

    CityCat4
    @CityCat4 Куратор тега C
    //COPY01 EXEC PGM=IEBGENER
    А почему должно? Это С, не С++, не перл, где существуют самые дикие конструкции. Здесь все просто как полено :)
    char domen[100];
    char stroka = "В чащах юга жил бы цитрус";
    
    strcpy(domen, stroka);

    Оператор sizeof возвращает длину типа. Вам он вернет 1, потому что длина типа char - 1 байт :)
    Если хотите сформировать одну длинную строку - то индекс можно вычислять, но если слева стоит что-то типа domen[N], то справа может быть только литерал. Для записи в массив строки с определенной позиции нужно использовать все то же strcpy()
    Ответ написан
    4 комментария
  • Статический и динамический массив в С?

    CityCat4
    @CityCat4 Куратор тега C
    //COPY01 EXEC PGM=IEBGENER
    Так сделать просто нельзя :)

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

    Кроме того, вместо malloc привыкайте сразу использовать calloc - это спасет от SIGSEGV, возникающих у нубов "на ровном месте" просто из-за того, что забыли проинициализировать память, полученную от системы.
    Ответ написан
    1 комментарий
  • Что должно быть установлено на компьютере что бы запустить программу на C\C++?

    CityCat4
    @CityCat4 Куратор тега C
    //COPY01 EXEC PGM=IEBGENER
    В винде - обычно runtime C library, msvcpXX.dll, где вместо ХХ - номер, причем их до десятка может быть разных версий, MS обычно бесплатно раздает инсталляторы.
    В линухе обычно все уже есть, там нужна обычно libc ну и другие, если использовались.
    Ответ написан
    Комментировать
  • Есть актуальные книги по Си?

    CityCat4
    @CityCat4 Куратор тега C
    //COPY01 EXEC PGM=IEBGENER
    Для С нет понятия "актуальная" и "неактуальная". Неактуальными могут быть средства разработки, упоминаемые в книге, но все примеры будут работать (с поправкой на ось, конечно же)

    Например Уэйт, Прата, Мартин "Язык программирования С" - я по ней учился еще в лохматые 90-е. А что изменилось? Правильно, ничего. Для хелловорлда по-прежнему нужен
    #include <stdio.h>
    Ответ написан
    Комментировать
  • Что значит звёздочка после типа указателя?

    CityCat4
    @CityCat4 Куратор тега C
    //COPY01 EXEC PGM=IEBGENER
    Первая запись обьявляет переменную ptd указателем на double. Компилятор ожидает, что в данной переменной хранится адрес памяти ячейки, который указывает на переменную типа double, хотя сразу после обьявления в ней находится мусор - неопределенное значение.
    Вторая запись выделяет память под хранение переменных.
    sizeof(double) - получить размер переменной double для текущей платформы
    malloc - выделить память под десять переменных размером в double - обычная вещь для массива например.
    (double *) - привести тип возвращаемого значения (malloc всегда возвращает void) к типу "указатель на double"

    Надо сказать, что данный код можно использовать только в том случае, если сразу за malloc() идет чтение или инициализация массива. Потому что malloc() вернул область памяти, заполненную случайными данными. Для гарантии, что там не будет мусора лучше использовать calloc:
    ptd = (double *) calloc(sizeof(double), 10);
    Ответ написан
    Комментировать
  • Какую программную среду использовать для обучения языку программирования C?

    CityCat4
    @CityCat4 Куратор тега C
    //COPY01 EXEC PGM=IEBGENER
    Eclipse

    Хотя я давно не использую никакой, потому что под виндой не пишу - она у меня только для игрушек - а в линухе всегда только текстовый редактор и gmake - потому что обычно работать приходится не на своем компе, а по ssh.
    Ответ написан
    Комментировать
  • Пустые круглые скобки у функции main() это нормально?

    CityCat4
    @CityCat4 Куратор тега C
    //COPY01 EXEC PGM=IEBGENER
    вы оставляете точку для входа, через которую программу можно взломать

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

    CityCat4
    @CityCat4 Куратор тега C
    //COPY01 EXEC PGM=IEBGENER
    На чистом С никто не пишет графические программы - слишком трудоемкий процесс. Чистый С - язык не для этого. Или Вы реально собираетесь создать либу виджетов на чистом С? Ну, дерзайте :)

    Здесь как раз обычно плюса используют - Qt, GTK...
    Ответ написан
    2 комментария
  • Как сделать scanf( ) необязательной для заполнения?

    CityCat4
    @CityCat4 Куратор тега C
    //COPY01 EXEC PGM=IEBGENER
    Ну наверное ... реализовать предложенный Вами алгоритм :) Просто вместо scanf() применять другие функции чтения, gets() например. И считывать, что приехало. Если "\n" или "\0" (мы же правильные программисты, мы же инициализируем области перед использованием :D) - нажимали [Enter].
    Если же gets() ведет себя так же - значит на более низкий уровень опускаться...
    Ответ написан
    Комментировать
  • Можно ли написать бота на языке си?

    CityCat4
    @CityCat4 Куратор тега C
    //COPY01 EXEC PGM=IEBGENER
    Конечно. Хоть на JCL. Открываешь любимый текстовый редактор - и лабаешь...
    Ответ написан
    Комментировать
  • Следует ли начинать изучение C++ с C?

    CityCat4
    @CityCat4 Куратор тега C
    //COPY01 EXEC PGM=IEBGENER
    Мне кажется, я видел уже такой вопрос...

    Дело в том, что C и C++ - это разные языки. По применимости.
    С - язык системного программирования, язык на котором пишут консольные утилиты, служебные программы, собственно систему etc. Он весьма низкоуровневый, в том смысле, что при работе на нем нужно точно знать, что тебе нужно и как этого достичь. Он вполне позволяет выстрелить себе в ногу, особенно на работе с памятью.
    С++ - язык прикладного программирования с классами, свистелками, пищалками и излучателями неприличных звуков :)
    Ответ написан
  • Посимвольный i/o vs i/o в строку (буфер)?

    CityCat4
    @CityCat4 Куратор тега C
    //COPY01 EXEC PGM=IEBGENER
    Это абсолютно верно. Посимвольного ввода-вывода (getchar()/putchar(), getc()/putc(), fgetc()/fputc()) стоит избегать как только можно. Если файл небольшой (и даже не очень большой) - его проще всего считать в память и уже в памяти его как угодно крутить-вертеть.
    Ответ написан
    Комментировать
  • Почему код именно так работает?

    CityCat4
    @CityCat4 Куратор тега C
    //COPY01 EXEC PGM=IEBGENER
    Потому что '0' - это совсем не нуль. Это ASCII-символ нуля с кодом 0x30. Поэтому сложив 10 (0xA) и '0' (0x30) Вы закономерно получили 0x3A :) Что является ASCII-кодом ':'

    Есть замечательный отладчик gdb, который может показывать изменение переменной в процессе работы программы и которым настоятельно рекомендуется пользоваться в спорных моментах. Вот например данная ситуация решается им в течение пары минут :)
    Ответ написан
    Комментировать
  • Как проверить элемент на NULL?

    CityCat4
    @CityCat4 Куратор тега C
    //COPY01 EXEC PGM=IEBGENER
    user_t usr;
    usr.name = NULL;
    
    if ((void *) usr.name == NULL)
      выделяем память сколько надо
     else
        память выделена, можно работать

    Первое присвоение - нужно, потому что сразу после обьявления в usr.name - мусор. Явное приведение к viod не обязательно, но компилятор может матюгаться на несовместимые типы.
    Ответ написан
  • Возможно ли использовать псевдонимы в С?

    CityCat4
    @CityCat4 Куратор тега C
    //COPY01 EXEC PGM=IEBGENER
    Я не понял, что есть "псевдоним" в данном контексте. Вы хотите передать в функцию адрес переменной, чтобы изменить ее значение? Используйте указатели, они для этого и придуманы.
    Ответ написан
    Комментировать
  • Что нужно знать для программирования железа?

    CityCat4
    @CityCat4 Куратор тега C
    //COPY01 EXEC PGM=IEBGENER
    Вполне возможно что и входит, смотря что делать :)
    Ответ написан
    Комментировать
  • Какой тип данных будет более правильным?

    CityCat4
    @CityCat4 Куратор тега C
    //COPY01 EXEC PGM=IEBGENER
    Утечка памяти не зависит от природы программы - ну, если Вы конечно не допустили глобального косяка типа забытого free() после malloc() Утечка памяти зависит от реализации ядра ОС.
    Использовать нужно всегда динамическую память. В статической разве что константы хранить.
    Почему? А очень просто получить эксплойт через переполнение границ массива.
    Вы, конечно, скажете - да я простой юзер, я модули ядра не пишу etc... на что я отвечу - а стиль программирования формируется. Привыкнув делать статические массивы - Вы и в модуле ядра будете делать так.
    Ответ написан
    Комментировать