免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: gaochang2008
打印 上一主题 下一主题

[算法] 不简单的strlen长度计算, [复制链接]

论坛徽章:
0
61 [报告]
发表于 2009-05-14 09:22 |只看该作者
原帖由 tbocd 于 2009-5-14 00:19 发表

这样行不?
int strlen(char *p)
{
    return (sizeof(p)/sizeof(char) - 1);
}



肯定不行了,p是一个指针,sizeof(p) == 4

论坛徽章:
5
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:53:172015亚冠之水原三星
日期:2015-06-02 16:34:202015年亚冠纪念徽章
日期:2015-10-19 18:13:37程序设计版块每日发帖之星
日期:2015-11-08 06:20:00
62 [报告]
发表于 2009-05-14 10:29 |只看该作者
原帖由 NeteLife 于 2009-5-14 09:21 发表




使用范围太狭窄了

_Strlen("aabbccdd"; // error
p = "aabbccdd";
_Strlen(p); // error


Just for


  1. char p[]="xxxxxxxxxxxxxxxxxxxxxxxx";

复制代码

论坛徽章:
0
63 [报告]
发表于 2009-05-14 13:21 |只看该作者

  1. #include <stdio.h>
  2. #include <string.h>

  3. int lenstr(char *p)
  4. {
  5.     __asm__ __volatile__(
  6.             "movb $0, %%al\n\t"
  7.             "movl $0XFFFFFFFF, %%ecx\n\t"
  8.             "cld\n\t"
  9.             "repne scasb\n\t"
  10.             "negl %%ecx\n\t"
  11.             "subl $2, %%ecx\n\t"
  12.             "movl %%ecx, %%edi\n\t"
  13.             :"=&D"(p)
  14.             :"0"(p)
  15.             :"eax", "ecx"
  16.             );
  17.     return (int)p;
  18. }

  19. int main(int argc, char* argv[])
  20. {
  21.     char * p = "i am a string!";

  22.     printf("%s=%d\n", p, lenstr(p));
  23.     printf("%s=%d\n", p, strlen(p));

  24.     return 0;
  25. }

  26. 13:17:10 root /mnt/windows/code/user-prg/mixed-c-asm # gcc strlen.c
  27. 13:17:30 root /mnt/windows/code/user-prg/mixed-c-asm # ./a.out
  28. i am a string!=14
  29. i am a string!=14
  30. 13:17:32 root /mnt/windows/code/user-prg/mixed-c-asm # uname -a
  31. Linux linux-2148 2.6.16.21-0.8-default #1 Mon Jul 3 18:25:39 UTC 2006 i686 i686 i386 GNU/Linux

  32. 这样也算是没有定义变量吧
复制代码

论坛徽章:
0
64 [报告]
发表于 2009-05-14 13:56 |只看该作者

回复 #63 sanbiangongzi 的帖子

还有一个版本

  1. int lenstr2(char *p)
  2. {
  3. #define i (*(int*)(&p - 3))
  4.     for(i=0; p[i]; i++);
  5.     return i;
  6. #undef i
  7. }
复制代码

论坛徽章:
0
65 [报告]
发表于 2009-05-14 14:06 |只看该作者
指针的地址减3是什么意思

论坛徽章:
0
66 [报告]
发表于 2009-05-14 15:04 |只看该作者

回复 #65 暗底 的帖子

|                    |  
  +--------------------+  
  |        p           |  
  |                    |  
  +--------------------+  
  |                    |  
  |        ret         |  
  +--------------------+  
  |                    |  
  |        ebp         |  
  +--------------------+  
  |                    |  
  |        here is &p-3|  
  +--------------------+  
  |                    |

论坛徽章:
0
67 [报告]
发表于 2009-05-14 15:09 |只看该作者
原帖由 sanbiangongzi 于 2009-5-14 13:21 发表

#include
#include

int lenstr(char *p)
{
    __asm__ __volatile__(
            "movb $0, %%al\n\t"
            "movl $0XFFFFFFFF, %%ecx\n\t"
            "cld\n\t"
            "repne  ...

这个仅适用于x86 CPU这种简单情况...

论坛徽章:
0
68 [报告]
发表于 2009-05-15 16:43 |只看该作者
呵呵,我首先想到的就是递归

论坛徽章:
0
69 [报告]
发表于 2009-05-15 16:50 |只看该作者
原帖由 daybreakcx 于 2009-5-13 18:44 发表
为了避免输出其他信息,在41楼基础上改成这样
int Strlen(char* p)
{
        return (sprintf(p,p));
}
当然,对于常量字符串就不行了,会出错的

如果p是数组是可以的,如果p是指向数组的指针则不行
如: char ar[100] sizeof(ar)/sizeof(char) 可以
char ar[100], *p=ar; sizeof(p)/sizeof(char)不行

论坛徽章:
0
70 [报告]
发表于 2009-05-15 17:58 |只看该作者
原帖由 皇家救星 于 2009-5-12 22:38 发表

int strlen(char *p)  // 注意! 不允许定义任何变量
{
  if( *p )
  return strlen(p + 1)+ 1;
  return 0;
}


您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP