Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 138, средняя оценка - 4.62
#pragma
Временно недоступен
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
#1

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

06.06.2009, 17:18. Просмотров 17801. Ответов 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));
Где сами алгоритмы функций?Что-то я запутался в этих файлах и не нашёл.Кто-нибудь может скопипастить/направить?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.06.2009, 17:18     Напишите свои аналоги функций strlen(), strcpy(), strcmp() и сравните с библиотечными.
Посмотрите здесь:

Есть в языке "С" аналоги функций Pos() и Delete()? C++
напишите в С++ программу-калькулятор арифметических функций C++
C++ Напишите программы для вычисления значений математических функций
Аналоги функций ord() и chr() C++
Не применяя библиотечных функций, напишите код функции C++
C++ Написать собственные аналоги функций strlen, strcmp, strchr, strcpy, strcat (дописать и исправить ошибки)
C++ STRCMP
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Evg
Эксперт CАвтор FAQ
17411 / 5649 / 355
Регистрация: 30.03.2009
Сообщений: 15,467
Записей в блоге: 26
14.04.2011, 16:58     Напишите свои аналоги функций strlen(), strcpy(), strcmp() и сравните с библиотечными. #21
Такой код кому-то может показаться избыточно длинным, но в случае длинных строк он будет работать в разы быстрее, чем примитивный код типа "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;
        }
    }
    }
}
redial
1 / 1 / 0
Регистрация: 05.12.2010
Сообщений: 3
23.04.2011, 15:14     Напишите свои аналоги функций strlen(), strcpy(), strcmp() и сравните с библиотечными. #22
А по какому принципу библиотечная strcmp выдаёт результат(т.е. модуль числа)?
Evg
Эксперт CАвтор FAQ
17411 / 5649 / 355
Регистрация: 30.03.2009
Сообщений: 15,467
Записей в блоге: 26
23.04.2011, 15:49     Напишите свои аналоги функций strlen(), strcpy(), strcmp() и сравните с библиотечными. #23
это не модуль, а результат (меньше, больше, равно): http://linux.die.net/man/3/strcmp
redial
1 / 1 / 0
Регистрация: 05.12.2010
Сообщений: 3
23.04.2011, 16:02     Напишите свои аналоги функций strlen(), strcpy(), strcmp() и сравните с библиотечными. #24
Я имею в виду модуль результирующего числа,он же зависит от исходных строк.
Evg
Эксперт CАвтор FAQ
17411 / 5649 / 355
Регистрация: 30.03.2009
Сообщений: 15,467
Записей в блоге: 26
23.04.2011, 16:48     Напишите свои аналоги функций strlen(), strcpy(), strcmp() и сравните с библиотечными. #25
Цитата Сообщение от redial Посмотреть сообщение
Я имею в виду модуль результирующего числа,он же зависит от исходных строк.
Насколько я понимаю, сие никак не оговаривается. Оговаривается лишь то, что результат будет либо меньше нуля, либо равен нулю, либо больше нуля. Наверняка сие сказано в угоду производительности, чтобы не делать лишних телодвижений в функции и не привязываться к конкретному значению чисел
MrKarapuz
0 / 0 / 0
Регистрация: 09.11.2009
Сообщений: 3
29.05.2011, 19:25     Напишите свои аналоги функций strlen(), strcpy(), strcmp() и сравните с библиотечными. #26
быстрый вариант 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);
}
diagon
Higher
1924 / 1190 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
03.06.2011, 15:29     Напишите свои аналоги функций strlen(), strcpy(), strcmp() и сравните с библиотечными. #27
Также добрался до этого задания, написал свои варианты...
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;
}
Точно работает только первое, в остальных сомневаюсь, т.к. точно не знаю, как они работают=)
MIfodij
1 / 1 / 0
Регистрация: 14.07.2011
Сообщений: 12
12.08.2011, 11:40     Напишите свои аналоги функций strlen(), strcpy(), strcmp() и сравните с библиотечными. #28
Подскажите пожалуйста а если аналоги этих функций в С++?
diagon
Higher
1924 / 1190 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
12.08.2011, 11:42     Напишите свои аналоги функций strlen(), strcpy(), strcmp() и сравните с библиотечными. #29
Цитата Сообщение от MIfodij Посмотреть сообщение
Подскажите пожалуйста а если аналоги этих функций в С++?
Если вы про string, то size(), operator ==, operator =
Ну а так-то это то же с++, только в си стиле =)
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.08.2011, 13:03     Напишите свои аналоги функций strlen(), strcpy(), strcmp() и сравните с библиотечными.
Еще ссылки по теме:

Напишите варианты библиотечных функций strncpy, strncat и strncmp C++
C++ Написать программу: работа с си строками, функции strlen, strcpy
Как заменить функцию fgets на strlen и strcpy? C++
C++ Напишите алгоритм сортировки массива по возрастанию, без использования встроенных функций языка

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

Или воспользуйтесь поиском по форуму:
Evg
Эксперт CАвтор FAQ
17411 / 5649 / 355
Регистрация: 30.03.2009
Сообщений: 15,467
Записей в блоге: 26
12.08.2011, 13:03     Напишите свои аналоги функций strlen(), strcpy(), strcmp() и сравните с библиотечными. #30
Цитата Сообщение от MIfodij Посмотреть сообщение
Подскажите пожалуйста а если аналоги этих функций в С++?
Си++ опериует над строками в понятиях класса std::string
http://cplusplus.com/reference/string/string/
Yandex
Объявления
12.08.2011, 13:03     Напишите свои аналоги функций strlen(), strcpy(), strcmp() и сравните с библиотечными.
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru