2个C语言面试题,中的不用局部变量和全局变量实现strlen;

时间:2021-05-24 10:28:30
原帖地址http://topic.csdn.net/u/20110715/22/e070e207-d17d-437d-8785-893d186fb062.html?19866

我看见有人回答:

#include<stdio.h>

int mstrlen(char *p){
    if(*p =='\0') return 0;
        else return mstrlen(++p)+1;
}
main(){
char *pp="ddddddd";
printf("%d\n", mstrlen(pp));
}

看了有点不明白的地方。
我想问下,第一是不是所以字符串都会以'\0'结尾吗?那最后就返回的是0啊 (if(*p =='\0') return 0;)根据这句;
第二点是:mstrlen也像全局变量一样会被初始化为0啊?

13 个解决方案

#1


第一个:(if(*p =='\0') return 0;)
指针p 最先指向的是 字符串的 首地址,如果*p==0,则说明字符串为空,长度当然为0,
第二个:int mstrlen(char *p)
他的返回类型是int类型的, 返回值当然可以是0.这里并不是初始化,是函数的返回值!

#2


是*p == '\0' 

#3


if和else是两个过程,互不影响,如果进入了if,就不会进入else。
递归:
楼主可以用一个"ab"代入进去试一试,看看结果。。

#4


引用 1 楼 twhtwhtwhtwh 的回复:
第一个:(if(*p =='\0') return 0;)
指针p 最先指向的是 字符串的 首地址,如果*p==0,则说明字符串为空,长度当然为0,
第二个:int mstrlen(char *p)
他的返回类型是int类型的, 返回值当然可以是0.这里并不是初始化,是函数的返回值!

可能是我描述的不够清楚吧,这个回答不是我想问的还有(*p == '\0')如果我没理解错的话莫不是*p == 0 而是到达了字符串的结尾,c中每个字符串结尾都会有一个'\0'也就是EOF。

第二个不初始化的话,return mstrlen(++p)+1;这个是怎么来累加的。

#5


引用 3 楼 sjy88813 的回复:
if和else是两个过程,互不影响,如果进入了if,就不会进入else。
递归:
楼主可以用一个"ab"代入进去试一试,看看结果。。


正式因为我知道在执行了if语句后就不会执行后面的else语句所以我才问为什么(if(*p =='\0') return 0;)这句执行了之后返回值确不是0;每一个字符串最后一位都是'\0'。

#6


递归啊,刚开始执行else 直到最深层就是'\0’,返回0,这时候返回的是给上一层的mstrlen函数,不是你主函数里调用的地方,然后每回一层加1,最后不就是字符串长度了嘛

#7


很蛋疼啊,还是调用汇编吧

#8


引用 6 楼 qq376472696qq 的回复:
递归啊,刚开始执行else 直到最深层就是'\0’,返回0,这时候返回的是给上一层的mstrlen函数,不是你主函数里调用的地方,然后每回一层加1,最后不就是字符串长度了嘛

 嗯 是这样的 你打个断点调式下。。。刚才的确没理解你的意思

#9


引用 6 楼 qq376472696qq 的回复:
递归啊,刚开始执行else 直到最深层就是'\0’,返回0,这时候返回的是给上一层的mstrlen函数,不是你主函数里调用的地方,然后每回一层加1,最后不就是字符串长度了嘛

噢,我有点明白了。
你的意思是不是这样的 递归是这样的,第一次调用mstrlen如果不是空字符串的话,那么再调用mstrlen(实际上这个时候的mstrlen返回值还是未知的,)然后再调用mstrlen,直到最后返回值为0了,然后再开始一步一步向上计算mstrlen的返回值。

还有点疑问,就是调用mstrlen函数时在内存中空间是怎么分布的啊?

#10


引用 9 楼 china_ssl 的回复:
引用 6 楼 qq376472696qq 的回复:

递归啊,刚开始执行else 直到最深层就是'\0’,返回0,这时候返回的是给上一层的mstrlen函数,不是你主函数里调用的地方,然后每回一层加1,最后不就是字符串长度了嘛

噢,我有点明白了。
你的意思是不是这样的 递归是这样的,第一次调用mstrlen如果不是空字符串的话,那么再调用mstrlen(实际上这个时候的mstrlen返……

嗯 是这样的 
这是 mstrlen的 反汇编
int mstrlen(char *p){
004113C0 55               push        ebp  
004113C1 8B EC            mov         ebp,esp 
004113C3 81 EC C0 00 00 00 sub         esp,0C0h 
004113C9 53               push        ebx  
004113CA 56               push        esi  
004113CB 57               push        edi  
004113CC 8D BD 40 FF FF FF lea         edi,[ebp-0C0h] 
004113D2 B9 30 00 00 00   mov         ecx,30h 
004113D7 B8 CC CC CC CC   mov         eax,0CCCCCCCCh 
004113DC F3 AB            rep stos    dword ptr es:[edi] 
if(*p =='\0') return 0;
004113DE 8B 45 08         mov         eax,dword ptr [p] 
004113E1 0F BE 08         movsx       ecx,byte ptr [eax] 
004113E4 85 C9            test        ecx,ecx 
004113E6 75 06            jne         mstrlen+2Eh (4113EEh) 
004113E8 33 C0            xor         eax,eax 
004113EA EB 1A            jmp         mstrlen+46h (411406h) 
004113EC EB 18            jmp         mstrlen+46h (411406h) 
else return mstrlen(++p)+1;
004113EE 8B 45 08         mov         eax,dword ptr [p] 
004113F1 83 C0 01         add         eax,1 
004113F4 89 45 08         mov         dword ptr [p],eax 
004113F7 8B 4D 08         mov         ecx,dword ptr [p] 
004113FA 51               push        ecx  
004113FB E8 E1 FC FF FF   call        mstrlen (4110E1h) 
00411400 83 C4 04         add         esp,4 
00411403 83 C0 01         add         eax,1 
}
 

#11


学习了~~~

#12


“给定一个小点的输入,完整单步跟踪一遍。”是理解递归函数工作原理的不二法门!

#13


我去,今天笔试考到了,不会

#1


第一个:(if(*p =='\0') return 0;)
指针p 最先指向的是 字符串的 首地址,如果*p==0,则说明字符串为空,长度当然为0,
第二个:int mstrlen(char *p)
他的返回类型是int类型的, 返回值当然可以是0.这里并不是初始化,是函数的返回值!

#2


是*p == '\0' 

#3


if和else是两个过程,互不影响,如果进入了if,就不会进入else。
递归:
楼主可以用一个"ab"代入进去试一试,看看结果。。

#4


引用 1 楼 twhtwhtwhtwh 的回复:
第一个:(if(*p =='\0') return 0;)
指针p 最先指向的是 字符串的 首地址,如果*p==0,则说明字符串为空,长度当然为0,
第二个:int mstrlen(char *p)
他的返回类型是int类型的, 返回值当然可以是0.这里并不是初始化,是函数的返回值!

可能是我描述的不够清楚吧,这个回答不是我想问的还有(*p == '\0')如果我没理解错的话莫不是*p == 0 而是到达了字符串的结尾,c中每个字符串结尾都会有一个'\0'也就是EOF。

第二个不初始化的话,return mstrlen(++p)+1;这个是怎么来累加的。

#5


引用 3 楼 sjy88813 的回复:
if和else是两个过程,互不影响,如果进入了if,就不会进入else。
递归:
楼主可以用一个"ab"代入进去试一试,看看结果。。


正式因为我知道在执行了if语句后就不会执行后面的else语句所以我才问为什么(if(*p =='\0') return 0;)这句执行了之后返回值确不是0;每一个字符串最后一位都是'\0'。

#6


递归啊,刚开始执行else 直到最深层就是'\0’,返回0,这时候返回的是给上一层的mstrlen函数,不是你主函数里调用的地方,然后每回一层加1,最后不就是字符串长度了嘛

#7


很蛋疼啊,还是调用汇编吧

#8


引用 6 楼 qq376472696qq 的回复:
递归啊,刚开始执行else 直到最深层就是'\0’,返回0,这时候返回的是给上一层的mstrlen函数,不是你主函数里调用的地方,然后每回一层加1,最后不就是字符串长度了嘛

 嗯 是这样的 你打个断点调式下。。。刚才的确没理解你的意思

#9


引用 6 楼 qq376472696qq 的回复:
递归啊,刚开始执行else 直到最深层就是'\0’,返回0,这时候返回的是给上一层的mstrlen函数,不是你主函数里调用的地方,然后每回一层加1,最后不就是字符串长度了嘛

噢,我有点明白了。
你的意思是不是这样的 递归是这样的,第一次调用mstrlen如果不是空字符串的话,那么再调用mstrlen(实际上这个时候的mstrlen返回值还是未知的,)然后再调用mstrlen,直到最后返回值为0了,然后再开始一步一步向上计算mstrlen的返回值。

还有点疑问,就是调用mstrlen函数时在内存中空间是怎么分布的啊?

#10


引用 9 楼 china_ssl 的回复:
引用 6 楼 qq376472696qq 的回复:

递归啊,刚开始执行else 直到最深层就是'\0’,返回0,这时候返回的是给上一层的mstrlen函数,不是你主函数里调用的地方,然后每回一层加1,最后不就是字符串长度了嘛

噢,我有点明白了。
你的意思是不是这样的 递归是这样的,第一次调用mstrlen如果不是空字符串的话,那么再调用mstrlen(实际上这个时候的mstrlen返……

嗯 是这样的 
这是 mstrlen的 反汇编
int mstrlen(char *p){
004113C0 55               push        ebp  
004113C1 8B EC            mov         ebp,esp 
004113C3 81 EC C0 00 00 00 sub         esp,0C0h 
004113C9 53               push        ebx  
004113CA 56               push        esi  
004113CB 57               push        edi  
004113CC 8D BD 40 FF FF FF lea         edi,[ebp-0C0h] 
004113D2 B9 30 00 00 00   mov         ecx,30h 
004113D7 B8 CC CC CC CC   mov         eax,0CCCCCCCCh 
004113DC F3 AB            rep stos    dword ptr es:[edi] 
if(*p =='\0') return 0;
004113DE 8B 45 08         mov         eax,dword ptr [p] 
004113E1 0F BE 08         movsx       ecx,byte ptr [eax] 
004113E4 85 C9            test        ecx,ecx 
004113E6 75 06            jne         mstrlen+2Eh (4113EEh) 
004113E8 33 C0            xor         eax,eax 
004113EA EB 1A            jmp         mstrlen+46h (411406h) 
004113EC EB 18            jmp         mstrlen+46h (411406h) 
else return mstrlen(++p)+1;
004113EE 8B 45 08         mov         eax,dword ptr [p] 
004113F1 83 C0 01         add         eax,1 
004113F4 89 45 08         mov         dword ptr [p],eax 
004113F7 8B 4D 08         mov         ecx,dword ptr [p] 
004113FA 51               push        ecx  
004113FB E8 E1 FC FF FF   call        mstrlen (4110E1h) 
00411400 83 C4 04         add         esp,4 
00411403 83 C0 01         add         eax,1 
}
 

#11


学习了~~~

#12


“给定一个小点的输入,完整单步跟踪一遍。”是理解递归函数工作原理的不二法门!

#13


我去,今天笔试考到了,不会