我如何在c中使用指针数组?



基本上我有一个字符串数组,我需要检查它们是否按字典顺序排列(大小写不敏感,这意味着它是哪个无关紧要)。为此,我使用已经创建的strcmp函数并重新排列它,以便它是大写还是小写都无关紧要。但是当输入str_compare时,它不会进入while循环,而只是退出函数。有人知道为什么吗?下面是代码:

int main(){
...
char * banned_words[N];
...
if (!are_sorted(banned_words, n)) {
printf("Words are not sorted correctly!n");
free_strings(banned_words, n);
return ERROR;
}
...
}
bool are_sorted(char * strings[], int n) {
int length = n;
int result = 0;
for (int i = 0; i < length - 1; i++) {
result += str_compare(strings[i], strings[i + 1]);
}
if (result > 0)
return false;
else
return true;
}
int str_compare(char **str1, char **str2){
while (str1 && str2) {
if (str1 >= 'A' && str1 <='Z' && (str1 + 'a' - 'A') == str2){
**str1++;
**str2++;}
else if (str2 >= 'A' && str2<='Z' && (str2 + 'a' - 'A') == str1){
**str1++;
**str2++;}
else if (str1 == *str2){
**str1++;
**str2++;}
else break;
}
if (str1 >= 'A' && str1<='Z')
return (str1 +'a' - 'A') - str2;
else if (str2 >= 'A' && str2<='Z')
return str1 - (str2 +'a'-'A');
else return str1 - str2;
}

使用char *类型的表达式调用函数str_compare

result += str_compare(strings[i], strings[i + 1]);

功能参数类型为char **

int str_compare(char **str1, char **str2){

这个while循环

while (str1 && str2) 

调用未定义的行为,因为当至少一个指针变为空指针时,循环的条件计算为false。

同样在if语句中的函数条件中,例如

if (str1 >= 'A' && str1 <='Z' && (str1 + 'a' - 'A') == str2){

else if (str1 == *str2){

没有意义。比较操作数的类型不同

还有这个代码片段中的return语句

if (str1 >= 'A' && str1<='Z')
return (str1 +'a' - 'A') - str2;
else if (str2 >= 'A' && str2<='Z')
return str1 - (str2 +'a'-'A');
else return str1 - str2;

可以产生不可预测的结果。

函数are_sorted

中的代码片段
for (int i = 0; i < length - 1; i++) {
result += str_compare(strings[i], strings[i + 1]);
}
if (result > 0)
return false;
else
return true;

实际上并不决定字符串数组是否已排序。例如,一对字符串的比较可以产生-1,而另一对字符串的比较可以产生1,结果将等于0,尽管数组没有排序。

函数str_compare可以如下面的示例程序所示定义:

#include <stdio.h>
#include <ctype.h>
int str_compare( const char *s1, const char *s2 )
{
char c1 = '', c2 = '';
while ( *s1 && ( c1 = tolower( ( unsigned char )*s1 ) ) == ( c2 = tolower( ( unsigned char) *s2 ) ) )
{
++s1;
++s2;
}
return islower( ( unsigned char )*s1 ) && islower( ( unsigned char ) *s2 ) 
?  c1 - c2 
: *s1 - *s2;
}    
int main(void) 
{
const char *s1 = "HeLlO";
const char *s2 = "hElLo";
printf( ""%s" == "%s" is %d", s1, s2, str_compare( s1, s2 ) );
return 0;
}

程序输出为

"HeLlO" == "hElLo" is 0

如果您可能不使用标准的C函数tolower,那么函数str_compare可以如下所示

int str_compare( const char *s1, const char *s2 )
{
char c1 = '', c2 = '';
while ( 1 )
{
c1 = *s1; c2 = *s2;
if (  'A' <= c1 && c1 <= 'Z' ) c1 += 'a' - 'A';
if (  'A' <= c2 && c2 <= 'Z' ) c2 += 'a' - 'A';
if ( c1 != c2 || c1 == '' ) break;
++s1; ++s2;
} 
return 'a' <= c1 && c1 <= 'z' && 'a' <= c2 && c2 <= 'z' 
? c1 - c2 : *s1 - *s2;
}

对于函数are_sorted,它可以这样定义

bool are_sorted( char * strings[], size_t n ) 
{
size_t i = n;
if ( n != 0 )
{ 
++i;
while ( i != n && str_compare( strings[i-1], strings[i] ) <= 0 ) ++i;
}  
return i == n ;
}

相关内容

  • 没有找到相关文章

最新更新