哪根弦最长
Which string is the longest
我的代码:
我想要做的是输入两个字符串,然后 return 最长的一个。如果它们的长度相同,则 return NULL。现在,代码只是输出乱码,我无法找出原因。函数 return 是指向最大字符串的第一个字符的指针。然后它通过 while 循环,我试图取消引用指针并打印出它的值。
注意:我正在复习考试,我们只能使用指针,不能将字符串视为数组。
#include<stdio.h>
char* string_ln(char*, char*);
int main() {
char str1[20];
char str2[20];
char* length;
scanf("%s%s", str1, str2);
length = string_ln(str1, str2);
while (length != '[=10=]') {
printf("%c", *length);
length++;
}
}
char* string_ln(char*p1, char*p2) {
int count1 = 0;
while (*p1 != '[=10=]') {
count1++;
p1++;
}
int count2 = 0;
while (*p2 != '[=10=]') {
count2++;
p2++;
}
if (count1 > count2) {
return p1;
}
else if (count2 > count1) {
return p2;
}
else {
return NULL;
}
}
我认为您没有取消对指针的引用。而不是
while(length!='[=10=]')
你需要
while(*length!='[=11=]')
就是说,在被调用的函数中,您在增量之后重复指针,即 returned 指针不再指向字符串的开头。您需要确保 return 指向字符串开头的指针。您可以将代码更改为
int count1 = 0;
while (p1[count1] != '[=12=]') {
count1++;
}
int count2 = 0;
while (p2[count2] != '[=12=]') {
count2++;
}
这样 p1
和 p2
就不会改变。
这里有一些问题。首先,您要在函数中修改 p1
和 p2
,因此实际上 return 不是指向最大字符串开头的指针,而是指向其结尾的指针。避免这种情况的一种方法是迭代 p1
和 p2
:
的副本
char* string_ln(char*p1, char*p2)
{
char* tmp1 = p1;
int count1 = 0;
while (*tmp1 != '[=10=]') {
count1++;
tmp1++;
}
char* tmp2 = p2;
int count2 = 0;
while (*tmp2 != '[=10=]') {
count2++;
tmp2++;
}
if(count1>count2){
return p1;
}
else if(count2>count1){
return p2;
}
else{
return NULL;
}
}
其次,在您的 main 中,您使用的是 %c 格式字符串,它适用于单个 char
,而不是整个字符串。由于无论如何你都有一个字符串,你可以避免格式字符串并直接打印它。另外,请注意,您应该明确检查 NULL
s:
int main() {
char str1[20];
char str2[20];
char* longest;
scanf("%s%s", str1, str2);
longest = string_ln(str1, str2);
if (longest) {
printf(longest);
} else {
printf("They are the same length");
}
}
在写作 string_ln
时,您完全遍历两个字符串以找到它们的长度,然后比较这些数字。这可行,但您实际上 不需要 执行此操作。你只需要知道哪个更长。更长的字符串有多长并不重要。
char *string_ln(char *str1, char *str2) {
char *iter1, *iter2;
for (iter1 = str1, iter2 = str2;
*iter1 && *iter2;
iter1++, iter2++);
if (!(*iter1 || *iter2)) {
return NULL;
}
else if (*iter1) {
return str1;
}
else {
return str2;
}
}
我们只需要遍历两个字符串,直到至少有一个字符串命中 NULL 字符。一旦我们到达那个点,我们就可以测试看看哪个迭代器是 NULL。如果两者都是,则它们的长度相同。如果第一个迭代器不为 NULL,则第一个字符串更长。否则,第二个字符串更长。
这种方法的好处是我们避免了不必要的工作,并且可以更快地比较不同长度的字符串。
对于初学者来说,函数应该这样声明
char * string_ln( const char *, const char * );
因为传递的字符串不会在函数内更改。
您正在 return 从函数中获取已修改的指针 p1 或 p2,该指针正在 while 循环之一中更改
while (*p1 != '[=11=]') {
count1++;
p1++;
}
while (*p2 != '[=11=]') {
count2++;
p2++;
}
因此 returned 指针指向字符串的终止零 '[=14=]'
。
而且在这个while循环之前的main中
长度=string_ln(str1, str2);
while(长度!='\0'){
printf("%c", *长度);
长度++;
}
您没有检查指针 length
是否等于 NULL
。因此,程序可以调用未定义的行为。
函数本身可以仅使用指针按以下方式定义。
char * string_ln( const char *p1, const char *p2 )
{
const char *s1 = p1;
const char *s2 = p2;
while ( *s1 != '[=12=]' && *s2 != '[=12=]' )
{
++s1;
++s2;
}
if ( *s1 == *s2 )
{
return NULL;
}
else if ( *s1 == '[=12=]' )
{
return ( char * )p2;
}
else
{
return ( char * )p1;
}
}
主要是你需要写
char *length = string_ln( str1, str2 );
if ( length != NULL )
{
while ( *length )
printf( "%c", *length++ );
}
注意函数的return类型是char *
而不是const char *
。这是因为在 C 中没有函数重载并且 returned 指针可以指向常量字符串或非常量字符串。这是 C 中声明字符串函数的通用约定。
我的代码: 我想要做的是输入两个字符串,然后 return 最长的一个。如果它们的长度相同,则 return NULL。现在,代码只是输出乱码,我无法找出原因。函数 return 是指向最大字符串的第一个字符的指针。然后它通过 while 循环,我试图取消引用指针并打印出它的值。
注意:我正在复习考试,我们只能使用指针,不能将字符串视为数组。
#include<stdio.h>
char* string_ln(char*, char*);
int main() {
char str1[20];
char str2[20];
char* length;
scanf("%s%s", str1, str2);
length = string_ln(str1, str2);
while (length != '[=10=]') {
printf("%c", *length);
length++;
}
}
char* string_ln(char*p1, char*p2) {
int count1 = 0;
while (*p1 != '[=10=]') {
count1++;
p1++;
}
int count2 = 0;
while (*p2 != '[=10=]') {
count2++;
p2++;
}
if (count1 > count2) {
return p1;
}
else if (count2 > count1) {
return p2;
}
else {
return NULL;
}
}
我认为您没有取消对指针的引用。而不是
while(length!='[=10=]')
你需要
while(*length!='[=11=]')
就是说,在被调用的函数中,您在增量之后重复指针,即 returned 指针不再指向字符串的开头。您需要确保 return 指向字符串开头的指针。您可以将代码更改为
int count1 = 0;
while (p1[count1] != '[=12=]') {
count1++;
}
int count2 = 0;
while (p2[count2] != '[=12=]') {
count2++;
}
这样 p1
和 p2
就不会改变。
这里有一些问题。首先,您要在函数中修改 p1
和 p2
,因此实际上 return 不是指向最大字符串开头的指针,而是指向其结尾的指针。避免这种情况的一种方法是迭代 p1
和 p2
:
char* string_ln(char*p1, char*p2)
{
char* tmp1 = p1;
int count1 = 0;
while (*tmp1 != '[=10=]') {
count1++;
tmp1++;
}
char* tmp2 = p2;
int count2 = 0;
while (*tmp2 != '[=10=]') {
count2++;
tmp2++;
}
if(count1>count2){
return p1;
}
else if(count2>count1){
return p2;
}
else{
return NULL;
}
}
其次,在您的 main 中,您使用的是 %c 格式字符串,它适用于单个 char
,而不是整个字符串。由于无论如何你都有一个字符串,你可以避免格式字符串并直接打印它。另外,请注意,您应该明确检查 NULL
s:
int main() {
char str1[20];
char str2[20];
char* longest;
scanf("%s%s", str1, str2);
longest = string_ln(str1, str2);
if (longest) {
printf(longest);
} else {
printf("They are the same length");
}
}
在写作 string_ln
时,您完全遍历两个字符串以找到它们的长度,然后比较这些数字。这可行,但您实际上 不需要 执行此操作。你只需要知道哪个更长。更长的字符串有多长并不重要。
char *string_ln(char *str1, char *str2) {
char *iter1, *iter2;
for (iter1 = str1, iter2 = str2;
*iter1 && *iter2;
iter1++, iter2++);
if (!(*iter1 || *iter2)) {
return NULL;
}
else if (*iter1) {
return str1;
}
else {
return str2;
}
}
我们只需要遍历两个字符串,直到至少有一个字符串命中 NULL 字符。一旦我们到达那个点,我们就可以测试看看哪个迭代器是 NULL。如果两者都是,则它们的长度相同。如果第一个迭代器不为 NULL,则第一个字符串更长。否则,第二个字符串更长。
这种方法的好处是我们避免了不必要的工作,并且可以更快地比较不同长度的字符串。
对于初学者来说,函数应该这样声明
char * string_ln( const char *, const char * );
因为传递的字符串不会在函数内更改。
您正在 return 从函数中获取已修改的指针 p1 或 p2,该指针正在 while 循环之一中更改
while (*p1 != '[=11=]') {
count1++;
p1++;
}
while (*p2 != '[=11=]') {
count2++;
p2++;
}
因此 returned 指针指向字符串的终止零 '[=14=]'
。
而且在这个while循环之前的main中
长度=string_ln(str1, str2);
while(长度!='\0'){ printf("%c", *长度); 长度++; }
您没有检查指针 length
是否等于 NULL
。因此,程序可以调用未定义的行为。
函数本身可以仅使用指针按以下方式定义。
char * string_ln( const char *p1, const char *p2 )
{
const char *s1 = p1;
const char *s2 = p2;
while ( *s1 != '[=12=]' && *s2 != '[=12=]' )
{
++s1;
++s2;
}
if ( *s1 == *s2 )
{
return NULL;
}
else if ( *s1 == '[=12=]' )
{
return ( char * )p2;
}
else
{
return ( char * )p1;
}
}
主要是你需要写
char *length = string_ln( str1, str2 );
if ( length != NULL )
{
while ( *length )
printf( "%c", *length++ );
}
注意函数的return类型是char *
而不是const char *
。这是因为在 C 中没有函数重载并且 returned 指针可以指向常量字符串或非常量字符串。这是 C 中声明字符串函数的通用约定。