Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.55/209: Рейтинг темы: голосов - 209, средняя оценка - 4.55
Временно недоступен
 Аватар для #pragma
957 / 228 / 14
Регистрация: 12.04.2009
Сообщений: 926

Напишите свои аналоги функций strlen(), strcpy(), strcmp() и сравните с библиотечными.

06.06.2009, 17:18. Показов 40076. Ответов 29
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Напишите свои аналоги функций strlen(),strcpy(),strcmp() и сравните с библиотечными.
Наивно написал эти функции:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
int strlen(char* c_str)
{
    int count=0;
    while(*c_str++) ++count;
    return count;
}
 
/************************************************/
 
void strcpy(char* c_str1,char* c_str2)
{
    while(*c_str2++=*c_str1++);
}
 
/************************************************/
 
int strcmp(char* c_str1,char* c_str2)
{
    if (strlen(c_str1)!=strlen(c_str2)) return 0;
    int count=strlen(c_str1)+1;
    while(*c_str1++==*c_str2++) --count;
    if (count) return 0;
    return 1;
}
Смотрю в библиотеке и вижу это(в файле string.h):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
/* Copy SRC to DEST.  */
extern char *strcpy (char *__restrict __dest, __const char *__restrict __src)
     __THROW __nonnull ((1, 2));
 
/************************************************/
 
extern int strcmp (__const char *__s1, __const char *__s2)
     __THROW __attribute_pure__ __nonnull ((1, 2));
 
/************************************************/
 
extern size_t strlen (__const char *__s)
     __THROW __attribute_pure__ __nonnull ((1));
Где сами алгоритмы функций?Что-то я запутался в этих файлах и не нашёл.Кто-нибудь может скопипастить/направить?
2
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
06.06.2009, 17:18
Ответы с готовыми решениями:

Написать собственные аналоги функций strlen, strcmp, strchr, strcpy, strcat (дописать и исправить ошибки)
вот задание: Написать собственные аналоги функций strlen, strcmp, strchr, strcpy, strcat из стандартной библиотеки cstring (string.h). ...

Реализовать собственные функции strcat, strcpy, strcmp, strlen
Добрый день. Помогите с задачей. Необходимо реализовать собственные функции strcat, strcpy, strcmp, strlen. Для strlen реализовал, а...

Рекурсивная реализация strcat, stracpy, strcmp и strlen
Introduce strcat (), stracpy (), strcmp () и strlen () recursively.

29
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
14.04.2011, 16:58
Студворк — интернет-сервис помощи студентам
Такой код кому-то может показаться избыточно длинным, но в случае длинных строк он будет работать в разы быстрее, чем примитивный код типа "while (*s++ != 0)". Принцип основан на том, что по строке программа идёт не по одному байту, а по 4 или 8 байт за одну итерацию цикла. И сразу 4 байта анализирует за раз. В таком коде на длинных строках будет, соответственно, в 4 или 8 раз меньше итераций цикла, но одна итерация будет немного больше, чем в побайтном случае. Вот вариант кода из glibc, он написан на Си, а потому будет более понятен. Да и комментарий там более внятный. Это некое "общее" решение, не заточенное под конкретну архитектуру. Хотя многие архитектуры используют коды, написанные на ассемблере

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/* Return the length of the null-terminated string STR.  Scan for
   the null terminator quickly by testing four bytes at a time.  */
size_t
strlen (str)
     const char *str;
{
  const char *char_ptr;
  const unsigned long int *longword_ptr;
  unsigned long int longword, magic_bits, himagic, lomagic;
 
  /* Handle the first few characters by reading one character at a time.
     Do this until CHAR_PTR is aligned on a longword boundary.  */
  for (char_ptr = str; ((unsigned long int) char_ptr
            & (sizeof (longword) - 1)) != 0;
       ++char_ptr)
    if (*char_ptr == '\0')
      return char_ptr - str;
 
  /* All these elucidatory comments refer to 4-byte longwords,
     but the theory applies equally well to 8-byte longwords.  */
 
  longword_ptr = (unsigned long int *) char_ptr;
 
  /* Bits 31, 24, 16, and 8 of this number are zero.  Call these bits
     the "holes."  Note that there is a hole just to the left of
     each byte, with an extra at the end:
 
     bits:  01111110 11111110 11111110 11111111
     bytes: AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD
 
     The 1-bits make sure that carries propagate to the next 0-bit.
     The 0-bits provide holes for carries to fall into.  */
  magic_bits = 0x7efefeffL;
  himagic = 0x80808080L;
  lomagic = 0x01010101L;
  if (sizeof (longword) > 4)
    {
      /* 64-bit version of the magic.  */
      /* Do the shift in two steps to avoid a warning if long has 32 bits.  */
      magic_bits = ((0x7efefefeL << 16) << 16) | 0xfefefeffL;
      himagic = ((himagic << 16) << 16) | himagic;
      lomagic = ((lomagic << 16) << 16) | lomagic;
    }
  if (sizeof (longword) > 8)
    abort ();
 
  /* Instead of the traditional loop which tests each character,
     we will test a longword at a time.  The tricky part is testing
     if *any of the four* bytes in the longword in question are zero.  */
  for (;;)
    {
      /* We tentatively exit the loop if adding MAGIC_BITS to
     LONGWORD fails to change any of the hole bits of LONGWORD.
 
     1) Is this safe?  Will it catch all the zero bytes?
     Suppose there is a byte with all zeros.  Any carry bits
     propagating from its left will fall into the hole at its
     least significant bit and stop.  Since there will be no
     carry from its most significant bit, the LSB of the
     byte to the left will be unchanged, and the zero will be
     detected.
 
     2) Is this worthwhile?  Will it ignore everything except
     zero bytes?  Suppose every byte of LONGWORD has a bit set
     somewhere.  There will be a carry into bit 8.  If bit 8
     is set, this will carry into bit 16.  If bit 8 is clear,
     one of bits 9-15 must be set, so there will be a carry
     into bit 16.  Similarly, there will be a carry into bit
     24.  If one of bits 24-30 is set, there will be a carry
     into bit 31, so all of the hole bits will be changed.
 
     The one misfire occurs when bits 24-30 are clear and bit
     31 is set; in this case, the hole at bit 31 is not
     changed.  If we had access to the processor carry flag,
     we could close this loophole by putting the fourth hole
     at bit 32!
 
     So it ignores everything except 128's, when they're aligned
     properly.  */
 
      longword = *longword_ptr++;
 
      if (
#if 0
      /* Add MAGIC_BITS to LONGWORD.  */
      (((longword + magic_bits)
 
        /* Set those bits that were unchanged by the addition.  */
        ^ ~longword)
 
       /* Look at only the hole bits.  If any of the hole bits
          are unchanged, most likely one of the bytes was a
          zero.  */
       & ~magic_bits)
#else
      ((longword - lomagic) & himagic)
#endif
      != 0)
    {
      /* Which of the bytes was the zero?  If none of them were, it was
         a misfire; continue the search.  */
 
      const char *cp = (const char *) (longword_ptr - 1);
 
      if (cp[0] == 0)
        return cp - str;
      if (cp[1] == 0)
        return cp - str + 1;
      if (cp[2] == 0)
        return cp - str + 2;
      if (cp[3] == 0)
        return cp - str + 3;
      if (sizeof (longword) > 4)
        {
          if (cp[4] == 0)
        return cp - str + 4;
          if (cp[5] == 0)
        return cp - str + 5;
          if (cp[6] == 0)
        return cp - str + 6;
          if (cp[7] == 0)
        return cp - str + 7;
        }
    }
    }
}
2
1 / 1 / 0
Регистрация: 05.12.2010
Сообщений: 3
23.04.2011, 15:14
А по какому принципу библиотечная strcmp выдаёт результат(т.е. модуль числа)?
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
23.04.2011, 15:49
это не модуль, а результат (меньше, больше, равно): http://linux.die.net/man/3/strcmp
0
1 / 1 / 0
Регистрация: 05.12.2010
Сообщений: 3
23.04.2011, 16:02
Я имею в виду модуль результирующего числа,он же зависит от исходных строк.
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
23.04.2011, 16:48
Цитата Сообщение от redial Посмотреть сообщение
Я имею в виду модуль результирующего числа,он же зависит от исходных строк.
Насколько я понимаю, сие никак не оговаривается. Оговаривается лишь то, что результат будет либо меньше нуля, либо равен нулю, либо больше нуля. Наверняка сие сказано в угоду производительности, чтобы не делать лишних телодвижений в функции и не привязываться к конкретному значению чисел
0
0 / 0 / 0
Регистрация: 09.11.2009
Сообщений: 3
29.05.2011, 19:25
быстрый вариант strlen для символов с размером 1,2,4 байта
требуеться sse2
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
//header
UINTPTR _fastcall   slen_b(const UINT8* pstr);
UINTPTR _fastcall   slen_w(const UINT16* pstr);
UINTPTR _fastcall   slen_d(const UINT32* pstr);
inline  UINTPTR slen_tselect(const void* pstr,tselect<1>)   {return slen_b((const UINT8*)pstr);}
inline  UINTPTR slen_tselect(const void* pstr,tselect<2>)   {return slen_w((const UINT16*)pstr);}
inline  UINTPTR slen_tselect(const void* pstr,tselect<4>)   {return slen_d((const UINT32*)pstr);}
template<class T> inline UINTPTR slen(const T* pstr)    {return slen_tselect(pstr,tselect<sizeof T>());};
 
//cpp
template<class T> __forceinline UINTPTR slen_sse2(const T* pstr){
    const T* ptr = pstr;
    if (ptr){
        if (!((UINTPTR)ptr & (sizeof T - 1))){
            vec_sse_proto<T>    a,b;
            a.setz();       //xorps xmm0,xmm0
            UINT32  result = (UINTPTR)ptr & 15;
            ptr = (T*)((UINT8*)ptr - result);
            result = 0xffffffff << result;
            b.load(ptr);    //movaps    xmm1,[ptr]
            b.pcmpeq(a);    //pcmpeq[b/w/d] xmm1,xmm0
            ptr += 16/sizeof T;
            result &= b.movemaskb();    //movemaskb r32,xmm1
            while(!result){
                b.load(ptr);
                b.pcmpeq(a);
                ptr += 16/sizeof T;
                result = b.movemaskb();     
            }
            result = bit_sf(result);
            ptr = (T*)((UINT8*)ptr + result - 16);
        }else{
            //если данные не выровнены по размеру типа
            while(*ptr++);
        }
    }
    return ptr - pstr;
}
 
UINTPTR  _fastcall  slen_b(const UINT8* pstr)   {return slen_sse2(pstr);}
UINTPTR  _fastcall  slen_w(const UINT16* pstr)  {return slen_sse2(pstr);}
UINTPTR  _fastcall  slen_d(const UINT32* pstr)  {return slen_sse2(pstr);}
быстрый вариант strcpy для символов с размером 1,2,4 байта
требуеться sse2
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
//header
UINTPTR _fastcall scopy_b(UINT8* pdest,const UINT8* psrc);
UINTPTR _fastcall scopy_w(UINT16* pdest,const UINT16* psrc);
UINTPTR _fastcall scopy_d(UINT32* pdest,const UINT32* psrc);
дописать
inline  UINTPTR scopy_tselect(void* pdest,const void* psrc,tselect<1>){
   return scopy_b((UINT8*)pdest,(const UINT8*)psrc);
}
inline  UINTPTR scopy_tselect(void* pdest,const void* psrc,tselect<2>){
   return scopy_w((UINT16*)pdest,(const UINT16*)psrc);
}
inline  UINTPTR scopy_tselect(void* pdest,const void* psrc,tselect<4>){
   return scopy_d((UINT32*)pdest,(const UINT32*)psrc);
}
template<class TYPE> inline UINTPTR scopy(TYPE* pdest,const TYPE* psrc) {
   return scopy_tselect(pdest,psrc,tselect<sizeof TYPE>());
}
//cpp
 template<class T> __forceinline UINTPTR scopy_sse2(T* pdest,const T* psrc){
    const T* ps = psrc;
    if (pdest && psrc){
        if (!((UINTPTR)ps & (sizeof T -1))){
            while((UINTPTR)ps & 15){
                if (!(*pdest++ = *ps++))
                    return ps-psrc;
            }
            while(1){
                vec_sse_proto<T> v,z;
                v.load(ps);     //movaps  xmm0,[src]
                z.setz();       //pxorps      xmm1,xmm1
                z.pcmpeq(v);        //pcmpeq[b/w/d]  xmm1,xmm0
                if (z.movemaskb())  //movemaskb  r32,xmm1
                    break;
                v.storeu_fast(pdest);   //movlps [dest],xmm0
                            //movhps [dest+8],xmm0
                ps += 16/sizeof T;
                pdest += 16/sizeof T;
            }
        }
        while(*pdest++ = *ps++);
    }
    return ps-psrc;
}
 
UINTPTR _fastcall   scopy_b(UINT8* pdest,const UINT8* psrc){
    return scopy_sse2(pdest,psrc);
}
UINTPTR _fastcall   scopy_w(UINT16* pdest,const UINT16* psrc){
    return scopy_sse2(pdest,psrc);
}
UINTPTR _fastcall   scopy_d(UINT32* pdest,const UINT32* psrc){
    return scopy_sse2(pdest,psrc);
}
0
Higher
 Аватар для diagon
1953 / 1219 / 120
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
03.06.2011, 15:29
Также добрался до этого задания, написал свои варианты...
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
unsigned str_len(const char * str){
    int i=-1;
    while (str[++i]);
    return i; 
}
char * str_cpy(const char * from, char * to){
    char * x=to;
    while(*to++=*from++);  //скреативил из книги
    return x;  //насчет этого не уверен
}
char * str_chr(char * str, char chr){ //лишняя, но пусть будет
    while(*str)
        if (*str++==chr) return --str;
    return 0;
}
short str_cmp(const char * a, const char * b){
    if (str_len(a)>str_len(b)) return -1;
    if (str_len(a)<str_len(b)) return 1;
    for (int i=0; a[i]; i++){
        if (a[i]>b[i]) return -1;
        if (a[i]<b[i]) return 1;
    }
    return 0;
}
Точно работает только первое, в остальных сомневаюсь, т.к. точно не знаю, как они работают=)
0
1 / 1 / 0
Регистрация: 14.07.2011
Сообщений: 12
12.08.2011, 11:40
Подскажите пожалуйста а если аналоги этих функций в С++?
0
Higher
 Аватар для diagon
1953 / 1219 / 120
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
12.08.2011, 11:42
Цитата Сообщение от MIfodij Посмотреть сообщение
Подскажите пожалуйста а если аналоги этих функций в С++?
Если вы про string, то size(), operator ==, operator =
Ну а так-то это то же с++, только в си стиле =)
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
12.08.2011, 13:03
Цитата Сообщение от MIfodij Посмотреть сообщение
Подскажите пожалуйста а если аналоги этих функций в С++?
Си++ опериует над строками в понятиях класса std::string
http://cplusplus.com/reference/string/string/
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
12.08.2011, 13:03
Помогаю со студенческими работами здесь

Как заменить функцию fgets на strlen и strcpy?
while (fgets(s1, sz_line, fp)) //будет прочитано 120 символов { // считаем длину текущей строки , будет в j j = 0; while...

Написать программу: работа с си строками, функции strlen, strcpy
С помощью данного алгоритма нужно вставить слово в конец и начало строки. С помощью strlen() узнать длину строки и длину слова, после...

Strlen, strcpy, strcmp
Сдрасти! помогите плиз нупке! int m_strlen(const char* a) { } void m_strcpy(char* a1, const char* a2)

Напишите свой аналог функций strlen()
Пожалуйста, помогите написать свой аналог функций strlen()!!!!

Сравните числа - значения функций
2. Сравните числа a) cos(3*pi/7) и cos(2*pi/9); b) tg(9*pi/7) и tg(6*pi/5) Я вот что не пойму, как сделать эту задачу, чтобы не...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
30
Ответ Создать тему
Новые блоги и статьи
Подключение Box2D v3 к SDL3 для Android: физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL3_image
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
Влияние грибов на сукцессию
anaschu 26.01.2026
Бифуркационные изменения массы гриба происходят тогда, когда мы уменьшаем массу компоста в 10 раз, а скорость прироста биомассы уменьшаем в три раза. Скорость прироста биомассы может уменьшаться за. . .
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
Установка Android SDK, NDK, JDK, CMake и т.д.
8Observer8 25.01.2026
Содержание блога Перейдите по ссылке: https:/ / developer. android. com/ studio и в самом низу страницы кликните по архиву "commandlinetools-win-xxxxxx_latest. zip" Извлеките архив и вы увидите. . .
Вывод текста со шрифтом TTF на Android с помощью библиотеки SDL3_ttf
8Observer8 25.01.2026
Содержание блога Если у вас не установлены Android SDK, NDK, JDK, и т. д. то сделайте это по следующей инструкции: Установка Android SDK, NDK, JDK, CMake и т. д. Сборка примера Скачайте. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru