C语言中sizeof与strlen区别2

2021年09月15日 阅读数:1
这篇文章主要向大家介绍C语言中sizeof与strlen区别2,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

1. 以字符串形式出现的,编译器都会为该字符串自动添加一个0做为结束符,如在代码中写"abc",那么编译器帮你存储的是"abc\0".html

2. 字符串直接量做为字符指针的初始值  express

  "hello"是一个字符串直接量,编译器将其做为const char*处理,与之相关联的内存空间位于内存的只读部分,即容许编译器重用指向等价字符串直接量的引用以优化内存使用,数组

即便程序  中使用了字符串直接量500次,编译器在内存中也只是建立了一个实例。例如: char *ptr = “hello”; 等价于 const char *ptr = “hello”; ide

字符串直接量"hello"关联的是只读内存,若是试图修改将出错,例如ptr[1] = ‘a’;是会引发错误的。函数

3. 字符串直接量做为基于栈的字符数组的初始值优化

    因为基于栈的变量不可能引用其余地方存储的内存,编译器会负责将字符串直接量复制到基于栈的数组内存中。spa

    例如: char stackArray[] = “hello”;指针

    作以下修改: stackArray[1] = ‘a’;是真确的。htm

4. 字符数组与字符指针对象

    字符数组的形式以下,会将字符直接量拷贝到栈上:

          char str[]   = "abc";             // 实际的数据存储: a b c \0,也就是增长了一个终结符\0

          char str[3] = {'a','b','c'};     // 实际的数据存储: a b c,并无在最后添加终结符

          char str[10] = {'a','b','c'};   // 实际的数据存储: a b c \0 \0 \0 \0 \0 \0 \0

   字符指针的形式以下:

          char *str = “abc”;               // 实际的数据存储: a b c \0,也就是增长了一个终结符\0

5. 类型的决定

    1). 数组的类型是由该数组所存放元素的类型以及数组自己的大小决定的

         如char s1[3]和char s2[4],s1的类型就是char[3],s2的类型就是char[4],也就是说尽管s1和s2都是字符数组,但二者的类型倒是不一样的。

    2). 字符串常量的类型能够理解为相应字符常量数组的类型

         如"abcdef"的类型就能够当作是const char[7],也就是说实际的数据存储为"abcdef\0"。

    3). 函数参数列表中的以数组类型书写的形式参数,编译器把其解释为普通的指针类型

         如对于void func(char sa[100],int ia[20],char *p),则sa的类型为char*,ia的类型为int*,p的类型为char*。

对于sizeof与strlen: 

1. sizeof操做符的结果类型是size_t,它在头文件中typedef为unsigned int类型。该类型保证能容纳实现所创建的最大对象的字节大小。

2. sizeof是算符,strlen是函数。

3. sizeof能够用类型作参数,strlen只能用char*作参数,且必须是以''\0''结尾的。

4. 数组作sizeof的参数不退化,传递给strlen就退化为指针了。

5. 大部分编译程序在编译的时候就把sizeof计算过了,是类型或是变量的长度这就是sizeof(x)能够用来定义数组维数的缘由。
    char str[20]="0123456789"; // str是编译期大小已经固定的数组
     int a=strlen(str); //  a=10; //strlen()在运行起肯定,计算的是实际长度
     int b=sizeof(str); //  而b=20; //sizeof()在编译期肯定,str的类型是int[20],计算的是占据内存的大小

6. strlen的结果要在运行的时候才能计算出来,是用来计算字符串的实际长度,不是类型占内存的大小。

7. sizeof后若是是类型必须加括弧,若是是变量名能够不加括弧。这是由于sizeof是个操做符不是个函数。
    char c;
    sizeof c;  //变量名能够不加括弧
8. 当适用于一个结构类型或变量, sizeof 返回实际的大小,
    当适用一静态地空间数组, sizeof 归还所有数组的尺寸。
    sizeof 操做符不能返回动态地被分派了的数组或外部的数组的尺寸

sizeof、strlen计算字符数组、字符指针空间

 

char str[] = "abc";  实际的数据存储: a b c \0,也就是增长了一个终结符\0 其类型为char[4]   VS: sizeof(str)=4     strlen(str) = 3
GCC: sizeof(str)=4     strlen(str) = 3
char str[]   = "abc"; 实际的数据存储: a b c \0,也就是增长了一个终结符\0 其类型为char[4]   VS: sizeof(str)=4     strlen(str) = 3
GCC: sizeof(str)=4     strlen(str) = 3
char str[] = {'a','b','c'}; 实际的数据存储: a b c,并无在最后添加终结符 其类型为char[3]   VS: sizeof(str)=3     strlen(str) = 15
GCC: sizeof(str)=3     strlen(str) = 6
char str[3] = {'a','b','c'}; 实际的数据存储: a b c,并无在最后添加终结符 其类型为char[3]   VS: sizeof(str)=3     strlen(str) = 15
GCC: sizeof(str)=3     strlen(str) = 6
char str[5] = {'a','b','c','d','e'};  实际的数据存储: a b c d e ,并无在最后添加终结符 其类型为char[5]   VS: sizeof(str)=5     strlen(str) = 19
GCC: sizeof(str)=5     strlen(str) = 8

char str[5] = {'a','b','c','d'};

实际的数据存储: a b c d \0(默认填充字符\0) 其类型为char[5]   VS: sizeof(str)=5     strlen(str) = 4
GCC: sizeof(str)=5     strlen(str) = 4
char *pstr = "abcde"; 实际的数据存储: a b c d e \0 pstr的类型为char* sizeof(pstr) = 4 ( 指针的数据存储空间,4个字节),strlen(pstr) = 5

总结一下:

1). sizeof的结果是类型的大小,区分类型以后,sizeof的结果也就命了,sizeof的结果是在编译期决定的,计算的占据的内存大小。

     srelen的结果是在运行期间决定,计算的是实际长度,strlen只能以char*做参数,以\0做为结束符, 以上的例子中,红色部分的strlen计算是错误的,

     由于在str的数据存储中并无 一个\0字符,因此strlen的结果看似有点异常。

2). 注意在计算sizeof的时候:

     char str[] = "abc";  类型为char[4],   sizeof(str) = 4*sizeof(char) = 4.

3). sizeof(express),其中的express在编译过程当中是不会被编译的,而是被替代类型。

     例如: int a = 1; sizeof(a=2);

     此时的express为a=2,在编译过程当中被替换为sizeof(int),因此在执行完以后,a仍然是等于1.

4). 对函数使用sizeof,在编译阶段会被替换为函数的返回值的类型取代

     例如: int f(){return 0;}  sizeof(f());的结果为4.

             void f(){}            sizeof(f());编译过程当中会出现错误,替换以后的sizoeof(void)编译没法经过.

原文参见:http://www.cnblogs.com/alex-tech/archive/2011/03/26/1996284.html