Бьерн Страуструп.
Язык программирования С++
85
for (int i = 0; q[i] !=0 ; i++) p[i] = q[i];
p[i] = 0;
// запись нулевого символа
Поскольку p и q - указатели, можно обойтись без переменной i, используемой для индексации:
while (*q !=0) {
*p = *q;
p++;
// указатель на следующий символ
q++;
// указатель на следующий символ
}
*p = 0;
// запись нулевого символа
Поскольку операция постфиксного инкремента позволяет сначала использовать значение, а затем уже
увеличить его, можно переписать цикл так:
while (*q != 0) {
*p++ = *q++;
}
*p = 0;
// запись нулевого символа
Отметим, что результат выражения *p++ = *q++ равен *q. Следовательно, можно переписать наш
пример и так:
while ((*p++ = *q++) != 0) { }
В этом варианте учитывается, что *q равно нулю только тогда, когда *q уже скопировано в *p, поэтому
можно исключить завершающее присваивание нулевого символа. Наконец, можно еще более сократить
запись этого примера, если учесть, что пустой блок не нужен, а операция "!= 0" избыточна, т.к.
результат условного выражения и так всегда сравнивается с нулем. В результате мы приходим к
первоначальному варианту, который вызывал недоумение:
while (*p++ = *q++) ;
Неужели этот вариант труднее понять, чем приведенные выше? Только неопытным программистам на
С++ или С! Будет ли последний вариант наиболее эффективным по затратам времени и памяти? Если
не считать первого варианта с функцией strlen(), то это неочевидно. Какой из вариантов окажется
эффективнее, определяется как спецификой системы команд, так и возможностями транслятора.
Наиболее эффективный алгоритм копирования для вашей машины можно найти в стандартной функции
копирования строк из файла
:
int strcpy(char*, const char*);
Достарыңызбен бөлісу: