独闷闷网

标题: sizeof函数不靠判断'\0',那么它是靠什么识别数组或者数据的长度?已解答。 [打印本页]

作者: jianhong_wu    时间: 2016-10-9 16:31
标题: sizeof函数不靠判断'\0',那么它是靠什么识别数组或者数据的长度?已解答。
问:
sizeof函数不靠判断'\0',那么它是靠什么识别数组或者数据的长度?

★坚鸿-深圳:
   sizeof涵数有点特殊,有必要讲讲,它特殊在哪?要讲sizeof的特殊性,必须先讲strlen涵数。
strlen涵数就是计算一个数组的总长度,原理是:靠识别十六进制的0x00为数组末尾结束符(也就是常说的“\0”的结束符),有了这个原理,我平时自己做项目从来不用strlen这个涵数,都是自己随手写一个涵数就能求字符串的长度。对于sizeof涵数,很多教程大意是这样讲的,sizeof涵数求字符串的长度是包含末尾结束符“\0”,而strlen不包。

   我一开始也不在意,直到某一天,我突然冒出一个问题“既然strlen靠结束符所以可以知长度,那么sizeof它靠什么知长度?”这个问题仔细想一想,既然sizeof没有结束符那它靠什么知长度?这背后一定有什么鲜为人知的秘密。原来,sizeof它的本质不是涵数,它是宏的预编译……它跟strlen不是同一类的。所谓的宏预编译,就不是单片机上电后的工作,而是编译器这个翻译家的份内工作,是给编译器看,让编译器在把C语言翻译成Hex文件之前,就根据sizeof的指示,把sizeof翻译出一个常量的数据(比如1,2,3这类常量),它并不是单片机计算的。在这里,sizeof看作是一个常量。既然知道sizeof是宏的预编译,那么就已经可以马上猜出来,编译器要预先知道某个变量或数组占多大内存,太容易了,因为上电之前,一个unsigned long占4个字节,10个这样的变量就占40个字节,这个编译器的工作很容易识别。但是如果你不知它是宏的预编译,而误以为是真的单片机执行的涵数,那么这个迷你永远也解不开。

    既然是C编译器预先做的,那么,编译器怎么知道下面这行代码占的内存是10个字节?

unsigned  char  a[10];

    很容易,编译器只要用提取这个“unsigned char ”字符和“[]”字符和“10”字符,就可以识别这个数组占10个字节。说白了它是像人一样靠眼睛一看就看出来了,不用计算。C编程器的角度是提取关键字符,是像人一样,看文字看符号。C编译器本身就是一个上位机软件,它的重点就是识别字符,预先识别我们编程者想告诉它什么信息。

    再看一个例子:

  1. char str[20]="0123456789";
  2. int a=strlen(str); //a等于10
  3. int b=sizeof(str); //而b等于20
复制代码



这个例子等效于以下:
  1. char str[20]="0123456789";
  2. int a=strlen(str); //a等于10
  3. int b=20;
复制代码



但是不等效于以下:
  1. char str[20]="0123456789";
  2. int a=10;
  3. int b=sizeof(str); //而b等于20。
复制代码

最后总结:
strlen是单片机执行的。
sizeof是编译器识别提前计算好的。






欢迎光临 独闷闷网 (http://www.dumenmen.com/) Powered by Discuz! X3.2