Программирование. Принципы и практика использования C++ Исправленное издание, стр. 394
Эта рекомендация относится как к языку C, так и к языку C++.
Функция
strchr()char* strchr(const char* s,int c); /* найти c в константной строке s (не C++) */const char aa[] = "asdf"; /* aa — массив констант */char* q = strchr(aa,'d'); /* находит символ 'd' */*q = 'x'; /* изменяет символ 'd' в строке aa на 'x' */
В языке C++ эта проблема решается с помощью немного измененного объявления стандартной библиотечной функции
strchr()char const* strchr(const char* s, int c); // найти символ c // в константной строке schar* strchr(char* s, int c); // найти символ c в строке sАналогично объявляется функция
strstr()27.5.2. Операции над байтами
В далеком средневековье (в начале 1980-х годов), еще до изобретения указателя
void*void*void*/* копирует n байтов из строки s2 в строку s1 (как функция strcpy): */void* memcpy(void* s1, const void* s2, size_t n);/* копирует n байтов из строки s2 в строку s1 (диапазон [s1:s1+n] может перекрываться с диапазоном [s2:s2+n]): */void* memmove(void* s1, const void* s2, size_t n);/* сравнивает n байтов из строки s2 в строку s1 (как функция strcmp): */int memcmp(const void* s1, const void* s2, size_t n);/* находит символ c (преобразованный в тип unsigned char) среди первых n байтов строки s: */void* memchr(const void* s, int c, size_t n);/* копирует символ c (преобразованный в тип unsigned char) в каждый из n байтов строки, на который ссылается указатель s: */void* memset(void* s, int c, size_t n);Не используйте эти функции в программах на языке C++. В частности, функция
memset()27.5.3. Пример: функция strcpy()
Определение функции
strcpy()char* strcpy(char* p, const char* q){ while (*p++ = *q++); return p;}Объяснение, почему этот код на самом деле копирует С-строку
qpПОПРОБУЙТЕ
Является ли корректной реализация функции
strcpy()
27.5.4. Вопросы стиля
Мы потихоньку втягиваемся в длинные и часто яростно оспариваемые вопросы стиля, которые, впрочем, часто не имеют большого значения. Мы объявляем указатель следующим образом:
char* p; // p — указатель на переменную типа charМы не принимаем стиль, продемонстрированный ниже.
char *p; /* p — нечто, что можно разыменовать, чтобы получить символ */Пробел совершенно игнорируется компилятором, но для программиста он имеет значение. Наш стиль (общепринятый среди программистов на языке С++) подчеркивает тип объявляемой переменной, в то время как альтернативный стиль (общепринятый среди программистов на языке С) делает упор на использовании переменной. Мы не рекомендуем объявлять несколько переменных в одной строке.
char c, *p, a[177], *f(); /* разрешено, но может ввести в заблуждение */Такие объявления часто можно встретить в старых программах. Вместо этого объявления следует размещать в нескольких строках, используя свободное место для комментариев и инициализации.
char c = 'a'; /* символ завершения ввода для функции f() */char* p = 0; /* последний символ, считанный функцией f() */char a[177]; /* буфер ввода */char* f(); /* считывает данные в буфер a; возвращает указатель на первый считанный символ */Кроме того, выбирайте осмысленные имена.
27.6. Ввод-вывод: заголовок stdio
В языке С нет потоков ввода-вывода
iostream<stdio.h>cincoutstdinstdoutiostreamios_base::sync_with_stdio()