powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / K&R 5.5 Указатели символов и функции. Корректен ли код ?
25 сообщений из 66, страница 1 из 3
K&R 5.5 Указатели символов и функции. Корректен ли код ?
    #38544452
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте.

Сначала приводится такой код

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
char *strcpy(char *s, const char *t)
{
   while ((*s = *t) != '\0')
   {
        s++;
        t++;
   }
  return s;
}



ЖЁСТКОЕ ПОРНО ВЫРЕЗАНОK&RSTRCPY(S, T) /* COPY T TO S; POINTER VERSION 1 */
CHAR *S, *T;
WHILE ((*S = *T) != '\0')
S++;
T++;


с ним я согласен. Далее

Код: plaintext
1.
2.
3.
4.
5.
char *strcpy(char *s, const char *t)
{
  while ((*s++ = *t++) != '\0');
  return s;
}




ЖЁСТКОЕ ПОРНО ВЫРЕЗАНОK&RSTRCPY(S, T) /* COPY T TO S; POINTER VERSION 2 */
CHAR *S, *T;
WHILE ((*S++ = *T++) != '\0')
;


Полностью ли корректен данный код ? Вспоминается пример.

Код: plaintext
1.
2.
int a=1;
int b=a++;



Ниже идёт комментарий :
K&RЗдесь увеличение S и T внесено в проверочную часть. Значением *T++ является
символ, на который указывал T до увеличения; постфиксная операция ++ не изменяет
T, пока этот символ не будет извлечен. Точно так же этот символ помещается в
старую позицию S, до того как S будет увеличено. Конечный результат заключается в
том, что все символы, включая завершающий \0, копируются из T в S.


Перечитал этот текст три раза, понял. И слева и справа происходит работа со старыми значениями, и только потом происходит инкремент.
Но если вы более пристально его изучите, то вы обратите внимание на то, что нигде не делается комментариев на то, что массивы должны быть равны. Я это заметил только в следующем примере:

K&RSTRCPY(S, T) /* COPY T TO S; POINTER VERSION 3 */
CHAR *S, *T;
WHILE (*S++ = *T++)
;


1 вопрос. Мне кажется что лучше узнать длину массива S (SIZEOF), сравнить с длиной T, и уже в дальнейшем в зависимости от полученных значений либо выводить сообщение о невозможности копирования, либо продумать варианты.
Вы наверное знаете что будет если попытаться скопировать массивы разной длины, я не знал. Хотя результат вероятно зависит от архитектуры.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
void strcpy_test(char* s, char* t)
{
	while (*s++ = *t++);
}
int _tmain(int argc, _TCHAR* argv[])
{
	char str1[] = "abc";
	char str2[] = "defjk";
	strcpy_test(str1, str2);
	printf("%s", str1);
	return 0;
}


на экране появились мои defjk и также Debug Error следом, но фактически, как я понял,j and k попали в те ячейки где совсем не должны были находиться и возможно что-то переписали. Это верно ? Прокомментируйте пожалуйста рассуждения, в чём я ошибаюсь или не ошибаюсь?
2. Вообще не нравится конструкция while (*s++ = *t++); У меня сразу чувство что я буду путешевствовать по всем ячейка памяти. Хотя, видимо компилятор действительно знает что это массив, и если длины массивов одинаковые, то всё ок.
Это нормальная конструкция в целом ? Насколько она безопасная ?
...
Рейтинг: 0 / 0
K&R 5.5 Указатели символов и функции. Корректен ли код ?
    #38544496
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercury2. Вообще не нравится конструкция while (*s++ = *t++); У меня сразу чувство что я буду путешевствовать по всем ячейка памяти. Хотя, видимо компилятор действительно знает что это массив, и если длины массивов одинаковые, то всё ок.
Это нормальная конструкция в целом ? Насколько она безопасная ?
Эта конструкция предназначена только для строк. Т.е. в исходном буфере по любому встретится 0.
Буфер на который указывает s должен быть не меньше буфера t.
Проверить это никак нельзя, поэтому функция и не проверяет.
В случае если буфер будет меньше чем надо либо если в исходной строке нет завершающего нуля, то будет выход за границы массива, которое в С/С++ является UB (undefined behavior).
Не допустить этого - задача вызывающего кода.
...
Рейтинг: 0 / 0
K&R 5.5 Указатели символов и функции. Корректен ли код ?
    #38544525
SashaMercury,

Первый приведенный кусок кода не корректен и быстро приведет к segmentation fault.
...
Рейтинг: 0 / 0
K&R 5.5 Указатели символов и функции. Корректен ли код ?
    #38544576
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercury,

выложи код в нормальном виде.
...
Рейтинг: 0 / 0
K&R 5.5 Указатели символов и функции. Корректен ли код ?
    #38544584
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wst как гостэSashaMercury,

Первый приведенный кусок кода не корректен и быстро приведет к segmentation fault.

код без базара некорректен, потому что скобок нет .
были бы скобки, == был бы корректер на 100 %
...
Рейтинг: 0 / 0
K&R 5.5 Указатели символов и функции. Корректен ли код ?
    #38544592
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZiv,
так я просто копирую из книги(Она у меня в формате pdf )
Тоже раньше не понимал почему так, но потом понял,
код следует трактовать так:
K&R
STRCPY(CHAR *S, CHAR *T)
{
WHILE ((*S = *T) != '\0')
S++;
T++;
}
...
Рейтинг: 0 / 0
K&R 5.5 Указатели символов и функции. Корректен ли код ?
    #38544602
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercury,

Скобки опять забыл :)
...
Рейтинг: 0 / 0
K&R 5.5 Указатели символов и функции. Корректен ли код ?
    #38544627
Там не только скобок не хватает, еще и буквы слишком заглавные, если определять условием корректности кода как минимум его компилируеиость без кучи дефайнов.
...
Рейтинг: 0 / 0
K&R 5.5 Указатели символов и функции. Корректен ли код ?
    #38544688
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну что такое :)Исправил
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
STRCPY(CHAR *S, CHAR *T)
{
 WHILE ((*S = *T) != '\0')
   {
        S++;
        T++;
   }
}



Ответьте ещё на этот вопрос, пожалуйста )

S как я понял,j and k попали в те ячейки где совсем не должны были находиться и возможно что-то переписали. Это верно ?
...
Рейтинг: 0 / 0
K&R 5.5 Указатели символов и функции. Корректен ли код ?
    #38544720
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryОтветьте ещё на этот вопрос, пожалуйста )

S как я понял,j and k попали в те ячейки где совсем не должны были находиться и возможно что-то переписали. Это верно ?
k и \0. Строка в С обязательно завершается нулевым символом, поэтому str1[] = 'abc\0', а str2[]= 'defjk\0'. По сути же, верно мыслишь.
P.S. Ссылку на первоисточник опять потребуешь? ;))
...
Рейтинг: 0 / 0
K&R 5.5 Указатели символов и функции. Корректен ли код ?
    #38544730
В отладочном коде некоторые компиляторы оставляет вокруг данных в стеке свободное место и вставляют в код проверки что в эти области никто не писал. Аналогично для динамически выделяемой памяти. 'j' и 'k' попали в это свободное место. В релизе они просто попортили бы данные в стеке, дальнейшее уже в общем случае предсказать невозможно.
...
Рейтинг: 0 / 0
K&R 5.5 Указатели символов и функции. Корректен ли код ?
    #38544737
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercury
Код: plaintext
1.
WHILE


Какой смысл постить этот мусор из заглавных букв?
Постите то что вы пробуете компилировать, а не копируйте из книги.
И что за книга такая - выкинуть нафик и взять нормальную.
...
Рейтинг: 0 / 0
K&R 5.5 Указатели символов и функции. Корректен ли код ?
    #38544770
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Понял )))

egorych , не потребую )

Dima_T, White Owl, Anatoly Moskovsky, MasterZiv , mayton, Dimitry Sibiryakov, egorych
Всем спасибо за помощь на этой неделе! Вы сделали меня умнее. Всем хорошо отдохнуть !

Dima_T, вам ещё раз отдельно спасибо, за чудесное настроение после разбора прекрасного примера ! Когда вспоминаю ту задачку, сразу улыбаюсь C:

S
...
Рейтинг: 0 / 0
K&R 5.5 Указатели символов и функции. Корректен ли код ?
    #38544796
Фотография pureproft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky...
И что за книга такая - выкинуть нафик и взять нормальную.



Неужели уже выросло поколение, для которого K&R буквы не о чём?
...
Рейтинг: 0 / 0
K&R 5.5 Указатели символов и функции. Корректен ли код ?
    #38544827
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pureproftНеужели уже выросло поколение, для которого K&R буквы не о чём?
Если в книге по С написано WHILE то неважно кто автор :)
...
Рейтинг: 0 / 0
K&R 5.5 Указатели символов и функции. Корректен ли код ?
    #38544832
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pureproftAnatoly Moskovsky...И что за книга такая - выкинуть нафик и взять нормальную.Неужели уже выросло поколение, для которого K&R буквы не о чём?поновее издание найди
...
Рейтинг: 0 / 0
K&R 5.5 Указатели символов и функции. Корректен ли код ?
    #38544878
novexelf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SashaMercury,

брошу свои пять копеек :-)

автор1 вопрос. Мне кажется что лучше узнать длину массива S (SIZEOF), сравнить с длиной T, и уже в дальнейшем в зависимости от полученных значений либо выводить сообщение о невозможности копирования, либо продумать варианты.
Вы наверное знаете что будет если попытаться скопировать массивы разной длины, я не знал. Хотя результат вероятно зависит от архитектуры.


sizeof - размерность типа данных покажет, не так ли? поэтому чтобы узнать полный размер буфера нужно выполнить sizeof(type) * n, где n количество элементов массива, тогда получается, что нам нужно передавать этот самый n в функцию. И соответственно нужно передавать n и для источника и для приемника, чтобы на это не заморачиваться было решено, что эта головная боль ложится на плечи программиста вызывающего функцию, он должен следить чтобы память была выделена в нужном объеме.

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

http://ru.wikipedia.org/wiki/Переполнение_буфера

http://www.xakep.ru/post/23646/

2. Вообще не нравится конструкция while (*s++ = *t++); У меня сразу чувство что я буду путешевствовать по всем ячейка памяти. Хотя, видимо компилятор действительно знает что это массив, и если длины массивов одинаковые, то всё ок.
Это нормальная конструкция в целом ? Насколько она безопасная ?

Конструкция безопасна, если ее использовать соблюдая все требования - размеры буферов и терминальный символ.
...
Рейтинг: 0 / 0
K&R 5.5 Указатели символов и функции. Корректен ли код ?
    #38545029
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryMasterZiv,
так я просто копирую из книги(Она у меня в формате pdf )
Тоже раньше не понимал почему так, но потом понял,
код следует трактовать так:
K&RSTRCPY(CHAR *S, CHAR *T)
{
WHILE ((*S = *T) != '\0')
S++;
T++;
}


Мать, мать, мать ;%;*;%:;:%;? !

Где блин ты видел код на С в верхнем регистре ?
...
Рейтинг: 0 / 0
K&R 5.5 Указатели символов и функции. Корректен ли код ?
    #38545055
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryПолностью ли корректен данный код ? Вспоминается пример.

Код: plaintext
1.
2.
int a=1;
int b=a++;





Данные примеры полностью корректны и правильны (по крайней мере я не заметил ничего плохого).

И процитированный мной кусок тоже правильный, что вообще тебе там не нравится ?

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

Вот тогда будут проблемы.
А что плохого ты видишь в приведённом коде ?
...
Рейтинг: 0 / 0
K&R 5.5 Указатели символов и функции. Корректен ли код ?
    #38545064
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercury,

Код: plaintext
1.
void strcpy_test(char* s, char* t)



должно быть

Код: plaintext
1.
char* strcpy_test(char* to, const char* from)



const -спецификации давно уже есть и в чистом С, привыкай ВСЕГДА их использовать.
...
Рейтинг: 0 / 0
K&R 5.5 Указатели символов и функции. Корректен ли код ?
    #38545070
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercury,

авторна экране появились мои defjk и также Debug Error следом, но фактически, как я понял,j and k попали в те ячейки где совсем не должны были находиться и возможно что-то переписали. Это верно ? Прокомментируйте пожалуйста рассуждения, в чём я ошибаюсь или не ошибаюсь?


При копировании буфера большего размера в буфер меньшего размера (на два символа) произошло переполнение приёмного буфера,
это привело к защите памяти и остановке программы.

Печально то, что происходит ошибка при таких условиях далеко не всегда: в release режимах ничего не проверяется.
...
Рейтинг: 0 / 0
K&R 5.5 Указатели символов и функции. Корректен ли код ?
    #38545075
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
[quot pureproft]Anatoly Moskovsky...

Неужели уже выросло поколение, для которого K&R буквы не о чём?

Я кстати не читал ни K&R , ни даже почти не читал Страустрапа.
Ничего, живу как-то.
...
Рейтинг: 0 / 0
K&R 5.5 Указатели символов и функции. Корректен ли код ?
    #38545083
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
novexelf2. Вообще не нравится конструкция while (*s++ = *t++); У меня сразу чувство что я буду путешевствовать по всем ячейка памяти. Хотя, видимо компилятор действительно знает что это массив, и если длины массивов одинаковые, то всё ок.
Это нормальная конструкция в целом ? Насколько она безопасная ?


Это -- классическая реализация strcpy из первых юниксов, ничего некорректного тут нет.
Наоборот, во всех книгах приводится как пример того, насколько выразителен язык С.
(выразителен -- значит кода мало, а делает он много).
...
Рейтинг: 0 / 0
K&R 5.5 Указатели символов и функции. Корректен ли код ?
    #38545667
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryЗдравствуйте.

Сначала приводится такой код

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
char *strcpy(char *s, const char *t)
{
   while ((*s = *t) != '\0')
   {
        s++;
        t++;
   }
  return s;
}


Даже этот код я бы назвал извратом, не говоря о более компактных написаниях. Код должен быть читабельным, а в данном плане маркетинг с++ жертвует читабельностью чтобы показать компактность. Это именно маркетинг, т.к. есть более понятные написания с такой же производительностью.
Надо уметь эти извраты понимать, но писать их не советую, подумай о тех кто будет читать твой код после тебя. Любой нездоровый код (с точки зрения читабельности) можно писать только в одном случае - если нужна бОльшая производительность. Во всех остальных случаях лучше отдать приоритет читабельности кода.
Т.е. это лучше писать так
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
char *strcpy(char *s, const char *t)
{
  *s = *t;
   while (*s != 0)
   {
        s++;
        t++;
        *s = *t;
   }
  return s;
}


Да, это длинно и нудно, но зато понятно всем, даже тем кто мало знаком с Си.
...
Рейтинг: 0 / 0
K&R 5.5 Указатели символов и функции. Корректен ли код ?
    #38545695
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TДа, это длинно и нудно, но зато понятно всем, даже тем кто мало знаком с Си.

А мне слету понятна конструкция "while (*s++ = *t++)" а в вашу надо вдумываться чтоб понять.
Так что не надо ту про читаемость :)

ЗЫ. Есть такое понятие идиома. Это то что новичек не знает, а опытные понимают с полслова.
"*s++ = *t++" - это идиома, ее не надо перефразировать.
...
Рейтинг: 0 / 0
25 сообщений из 66, страница 1 из 3
Форумы / C++ [игнор отключен] [закрыт для гостей] / K&R 5.5 Указатели символов и функции. Корректен ли код ?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]