g*********s 发帖数: 1782 | 1 the following two str_cmp have the diff on the major loop. which one is
better?
the 1st seems better in the look. but it does have the side effect that
p and q are possibly pointing to unknown memory location.
so i prefer the 2nd. anyone agree?
int str_cmp(const char* str1, const char* str2) {
if ( str1 == str2 ) {
return 0;
}
if ( str1 == NULL || str2 == NULL ) {
return (str1 == NULL ? -1 : 1);
}
const char* p = str1;
const char* q = str2;
int res (0);
do {
if ( *p < *q ) {
res = -1;
}
else if ( *p > *q ) {
res = 1;
}
} while ( res == 0 && *p++ != '\0' && *q++ != '\0');
return res;
}
int str_cmp2(const char* str1, const char* str2) {
if ( str1 == str2 ) {
return 0;
}
if ( str1 == NULL || str2 == NULL ) {
return (str1 == NULL ? -1 : 1);
}
const char* p = str1;
const char* q = str2;
int res (0);
while ( true ) {
if ( *p < *q ) {
res = -1;
}
else if ( *p > *q ) {
res = 1;
}
if ( res != 0 || *p == '\0' ) {
break;
}
else {
p ++;
q ++;
}
}
return res;
} | M7 发帖数: 219 | 2 第二个函数不检查*q == '\0', 如果q比p短,q++就越界了。
【在 g*********s 的大作中提到】 : the following two str_cmp have the diff on the major loop. which one is : better? : the 1st seems better in the look. but it does have the side effect that : p and q are possibly pointing to unknown memory location. : so i prefer the 2nd. anyone agree? : int str_cmp(const char* str1, const char* str2) { : if ( str1 == str2 ) { : return 0; : } : if ( str1 == NULL || str2 == NULL ) {
| g*********s 发帖数: 1782 | 3 no, u don't need to check.
if q is shorter than p, then q will hit '\0' first, in this case the
comparison will lead to "res = 1".
since u already checked res != 0, the case of unequal lengths is already
covered.
actually even in the 1st code, *q++ != '\0' can be replaced with q++.
【在 M7 的大作中提到】 : 第二个函数不检查*q == '\0', 如果q比p短,q++就越界了。
| z****e 发帖数: 2024 | 4 1没事吧。这p,q都是local的,最后越界一下也无关紧要吧。
何况是const,想修改也没办法。
不过细致说来,2倒是最后会少一次++的操作。极其微弱的区别。
【在 g*********s 的大作中提到】 : the following two str_cmp have the diff on the major loop. which one is : better? : the 1st seems better in the look. but it does have the side effect that : p and q are possibly pointing to unknown memory location. : so i prefer the 2nd. anyone agree? : int str_cmp(const char* str1, const char* str2) { : if ( str1 == str2 ) { : return 0; : } : if ( str1 == NULL || str2 == NULL ) {
| c*****t 发帖数: 1879 | 5 Both are not good. Go read some existing code.
【在 g*********s 的大作中提到】 : the following two str_cmp have the diff on the major loop. which one is : better? : the 1st seems better in the look. but it does have the side effect that : p and q are possibly pointing to unknown memory location. : so i prefer the 2nd. anyone agree? : int str_cmp(const char* str1, const char* str2) { : if ( str1 == str2 ) { : return 0; : } : if ( str1 == NULL || str2 == NULL ) {
| g*********s 发帖数: 1782 | 6 bad in term of what?
【在 c*****t 的大作中提到】 : Both are not good. Go read some existing code.
| g*********s 发帖数: 1782 | 7 so this is good?
#ifndef _HAVE_STRING_ARCH_strcmp
# if __GNUC_PREREQ (3, 2)
# define strcmp(s1, s2) \
__extension__
\
({ size_t __s1_len, __s2_len;
\
(__builtin_constant_p (s1) && __builtin_constant_p (s2)
\
&& (__s1_len = strlen (s1), __s2_len = strlen (s2),
\
(!__string2_1bptr_p (s1) || __s1_len >= 4)
\
&& (!__string2_1bptr_p (s2) || __s2_len >= 4))
\
? __builtin_strcmp (s1, s2)
\
: (__builtin_constant_p (s1) && __string2_1bptr_p (s1)
\
&& (__s1_len = strlen (s1), __s1_len < 4)
\
? (__builtin_constant_p (s2) && __string2_1bptr_p (s2)
\
? __builtin_strcmp (s1, s2)
\
: __strcmp_cg (s1, s2, __s1_len))
\
: (__builtin_constant_p (s2) && __string2_1bptr_p (s2)
\
&& (__s2_len = strlen (s2), __s2_len < 4)
\
? (__builtin_constant_p (s1) && __string2_1bptr_p (s1)
\
? __builtin_strcmp (s1, s2)
\
: __strcmp_gc (s1, s2, __s2_len))
\
: __builtin_strcmp (s1, s2)))); })
# else
# define strcmp(s1, s2) \
__extension__
\
({ size_t __s1_len, __s2_len;
\
(__builtin_constant_p (s1) && __builtin_constant_p (s2)
\
&& (__s1_len = strlen (s1), __s2_len = strlen (s2),
\
(!__string2_1bptr_p (s1) || __s1_len >= 4)
\
&& (!__string2_1bptr_p (s2) || __s2_len >= 4))
\
? memcmp ((__const char *) (s1), (__const char *) (s2),
\
(__s1_len < __s2_len ? __s1_len : __s2_len) + 1)
\
: (__builtin_constant_p (s1) && __string2_1bptr_p (s1)
\
&& (__s1_len = strlen (s1), __s1_len < 4)
\
? (__builtin_constant_p (s2) && __string2_1bptr_p (s2)
\
? __strcmp_cc (s1, s2, __s1_len)
\
: __strcmp_cg (s1, s2, __s1_len))
\
: (__builtin_constant_p (s2) && __string2_1bptr_p (s2)
\
&& (__s2_len = strlen (s2), __s2_len < 4)
\
? (__builtin_constant_p (s1) && __string2_1bptr_p (s1)
\
? __strcmp_cc (s1, s2, __s2_len)
\
: __strcmp_gc (s1, s2, __s2_len))
\
: strcmp (s1, s2)))); })
# endif
【在 g*********s 的大作中提到】 : bad in term of what?
| c*****t 发帖数: 1879 | 8 "res" not useful. Wasted comparisons etc.
【在 g*********s 的大作中提到】 : bad in term of what?
| a****l 发帖数: 8211 | 9 这个解决方法固然是好的,不过对于回答"怎样写str_cmp函数"的问题来说,这个答案基
本上等于是作弊,因为它本质上是把str_cmp的数据传给系统里的另一个库函数调用进行
比较.
这让我想到了一个老笑话,在basic的时代,有的人答题弄不出解决方案,就左一个goto右
一个goto,最后悄悄的在一个地方把手算好的答案打印出来.
【在 g*********s 的大作中提到】 : so this is good? : #ifndef _HAVE_STRING_ARCH_strcmp : # if __GNUC_PREREQ (3, 2) : # define strcmp(s1, s2) \ : __extension__ : \ : ({ size_t __s1_len, __s2_len; : \ : (__builtin_constant_p (s1) && __builtin_constant_p (s2) : \
|
|