sizeof与strlen练习

简介: sizeof与strlen练习

练习之前请牢记下面这段话.这将是头脑清晰地关键.


提示:


  1. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。


  1. &数组名,这里的数组名表示整个数组,取出的是整个数组的地址。


  1. 除此之外所有的数组名都表示首元素的地址。



sizeof只关心()里面的类型,并不关心里面放的是什么,这点希望做题目时可以牢记.


strlen()括号里面的是地址,它只会通过访问括号里面的地址,往后一直寻找’\0’,直到’\0’才会停止.


一维数组


#include <stdio.h>
int main()
{
  int a[] = { 1,2,3,4 };
  printf("%d\n", sizeof(a));      //1
  printf("%d\n", sizeof(a + 0));    //2
  printf("%d\n", sizeof(*a));     //3
  printf("%d\n", sizeof(a + 1));    //4
  printf("%d\n", sizeof(a[1]));   //5
  printf("%d\n", sizeof(&a));     //6
  printf("%d\n", sizeof(*&a));    //7
  printf("%d\n", sizeof(&a + 1));   //8
  printf("%d\n", sizeof(&a[0]));    //9
  printf("%d\n", sizeof(&a[0] + 1));  //10
  return 0;
}


运行结果:


1 ->  16
2 ->  8
3 ->  4
4 ->  8
5 ->  4
6 ->  8
7 ->  16
8 ->  8
9 ->  8
10  ->  8


详细分析答案:


1.  16字节:   数组名a单独出现在sizeof()的括号中表示计算整个数组的大小,即4*4=16字节
2.  4/8字节:  a数组名不是单独出现,+0表示首地址表示表示首元素地址,地址的大小4/8字节
3.  4字节:    (*a)解引用得到的是数组首元素数组首元素是1,类型为整形,整形大小是4字节.
4.  4/8字节:  a+1表示数组第二个元素的地址.地址大小4/8字节.
5.  4字节:    a[1]表示数组的第二个元素,元素2的类型是整形,整形的大小是4字节.
6.  4/8字节:  &a表示是整个数组的地址,类型为int(*)[4].但是数组的地址也是地址,地址就是4/8字节.
7.  16字节    *&a表示对&a解引用,得到的是整个数组的地址.也可以理解为*和&符号是可以抵消的,即等价于sizeof(a);结果为4*4=16字节
8.  4/8个字节: &a+1表示指向数组最后一个元素的后面.因为&a的类型是int(*)[4],+1会跳过四个整形.
地址的大小就是4/8个字节.
9.  4/8字节:  &a[0]表示首元素的地址,地址大小为4/8字节.
10. 4/8字节:  (&a[0] + 1表示第二个元素的地址.4/8字节.



字符数组


情况1:


字符数组:


char arr[] = { ‘a’,‘b’,‘c’,‘d’,‘e’,‘f’ };


#include <stdio.h>
#include <string.h>
int main()
{
  char arr[] = { 'a','b','c','d','e','f' };
  printf("%d\n", sizeof(arr));      //1
  printf("%d\n", sizeof(arr + 0));    //2
  printf("%d\n", sizeof(*arr));     //3
  printf("%d\n", sizeof(arr[1]));     //4
  printf("%d\n", sizeof(&arr));     //5
  printf("%d\n", sizeof(&arr + 1));   //6
  printf("%d\n", sizeof(&arr[0] + 1));  //7
  printf("%d\n", strlen(arr));      //8
  printf("%d\n", strlen(arr + 0));    //9
  printf("%d\n", strlen(*arr));     //10
  printf("%d\n", strlen(arr[1]));     //11
  printf("%d\n", strlen(&arr));     //12
  printf("%d\n", strlen(&arr + 1));   //13
  printf("%d\n", strlen(&arr[0] + 1));  //14
  return 0;
}


答案分析:


1.  6字节:    表示整个数组的地址,1*6=6个字节
2.  4/8字节 : 首元素地址是4/8个字节.
3.  1字节:    *arr表示首元素是一个字符型,1个字节.
4.  1字节:    arr[1]表示数组的第二个元素,大小为1个字节.
5.  4/8个字节: &arr表示整个数组的地址,占4/8个字节.
6.  4/8个字节: &arr+1表示数组最后一个元素的后一个位置的地址.4/8个字节
7.  4/8个字节: 表示第二个元素的地址.4/8个字节


strlen函数从参数处开始,遇到’\0’才会停止.


8.随机值.:   由于该数组没有’\0’,所以会向后一直找直到碰到'\0',
9.随机值:  arr+0同样表示从数组的第一个元素,从第一个元素往后找,与上面一个道理.
10.报错:  strlen()括号里面是地址,所以会访问地址名为a的地址,a的ASCII码值是’97’,访问地址’97’,系统会报错
11.报错:  同理,访问数组第二个元素,地址名b的地址,系统报错
12.随机值: &arr取出的是整个数组的地址,地址还是从数组首地址开始往后找'\0'.
13.随机值: &arr的类型是char(*)[6],+1会跳过这个数组从数组后面开始找'\0'.
14.随机值: 从数组的第二个元素开始找'\0'.


情况2


字符数组:


char arr[] = “abcdef”;


#include <stdio.h>
#include <string.h>
int main()
{
  char arr[] = "abcdef";
  printf("%d\n", sizeof(arr));      //1
  printf("%d\n", sizeof(arr + 0));    //2
  printf("%d\n", sizeof(*arr));     //3
  printf("%d\n", sizeof(arr[1]));     //4
  printf("%d\n", sizeof(&arr));     //5
  printf("%d\n", sizeof(&arr + 1));   //6
  printf("%d\n", sizeof(&arr[0] + 1));  //7
  printf("%d\n", strlen(arr));      //8
  printf("%d\n", strlen(arr + 0));    //9
  printf("%d\n", strlen(*arr));     //10
  printf("%d\n", strlen(arr[1]));     //11
  printf("%d\n", strlen(&arr));     //12
  printf("%d\n", strlen(&arr + 1));   //13
  printf("%d\n", strlen(&arr[0] + 1));  //14
  return 0;
}


答案分析:


1.  7字节:    表示整个数组的地址,1*7=7个字节
2.  4/8字节:  首元素地址是4/8个字节.
3.  1字节:    *arr表示首元素是,一个字符型,1个字节.
4.  1字节:    arr[1]表示数组的第二个元素,大小为1个字节.
5.  4/8个字节: &arr表示整个数组的地址,占4/8个字节.
6.  4/8个字节: &arr+1表示数组最后一个元素的后一个位置的地址4/8个字节
7.  4/8个字节: 表示第二个元素的地址4/8个字节
8.  6字节:    从数组首元素开始,直到最后一个元素’\0’,共6个元素.6*1=6字节.
9.  6字节:    arr+0同样表示从数组的第一个元素,从第一个元素往后找,与上面一个道理.
10. 报错:   strlen()括号里面是地址,所以会访问地址名为a的地址,a的ASCII码值是’97’,访问地址’97’,系统会报错
11. 报错:   同理,访问数组第二个元素,地址名b的地址,系统报错
12. 6字节:    &arr取出的是整个数组的地址,地址还是从数组首地址开始往后找'\0’.
13. 随机值:    &arr的类型是char(*)[6],+1会跳过这个数组,从数组后面开始找'\0’.
14. 5字节:    从数组的第二个元素'b'开始往后找'\0'.


情况3


char* p = “abcdef”;


#include <stdio.h>
#include <string.h>
int main()
{
  char* p = "abcdef";
  printf("%d\n", sizeof(p));        //1
  printf("%d\n", sizeof(p + 1));      //2
  printf("%d\n", sizeof(*p));       //3
  printf("%d\n", sizeof(p[0]));     //4
  printf("%d\n", sizeof(&p));       //5
  printf("%d\n", sizeof(&p + 1));     //6
  printf("%d\n", sizeof(&p[0] + 1));    //7
  printf("%d\n", strlen(p));        //8
  printf("%d\n", strlen(p + 1));      //9
  printf("%d\n", strlen(*p));       //10
  printf("%d\n", strlen(p[0]));     //11
  printf("%d\n", strlen(&p));       //12
  printf("%d\n", strlen(&p + 1));     //13
  printf("%d\n", strlen(&p[0] + 1));    //14
  return 0;
}


答案分析:



1.  4/8字节:   p是一个指针变量,这里指向的是常量字符串,首元素’a’,指针大小4/8字节.
2.  4/8字节:  p+1表示指向第二个元素’b’,地址(指针)的大小为4/8字节.
3.  1字节:    *p表示首元素’a’,字符a是char类型,占一个字节.
4.  1字节:    p[0]同样是表示数组首元素,占一个字节.
5.  4/8个字节: &p表示一级指针变量p的地址,类型为char**的二级指针,指针大小为4/8字节.
6.  4/8个字节: 二级指针&p+1,表示该二级指针的后一个地址,请看图.指针大小4/8字节.
7.  4/8个字节: 表示首元素地址+1,即第二个元素地址,4/8个字节.
8 6字节     从字符串首元素开始,直到最后一个元素’\0’,共6个元素.6*1=6字节.
9 5字节   从字符串第二个元素往后,找’\0’,’bcdef’共5个元素
10. 报错:   表示从a地址,’97’地址往后找’\0’,系统报错.
11. 报错:   同理, 也是访问地址名为’97’的地址.系统报错.
12. 随机值   &p表示一级指针变量p的地址,从存放指针’p’的地址往后找’\0’.
13. 随机值:    &p+1表示从存放指针变量’p’的地址后面一个地址,找’\0’.
14  5字节:    从字符串的第二个元素开始找'\0'.


二维数组


//二维数组
#include <stdio.h>
int main()
{
  int a[3][4] = { 0 };
  printf("%d\n", sizeof(a));            //1
  printf("%d\n", sizeof(a[0][0]));        //2
  printf("%d\n", sizeof(a[0]));         //3
  printf("%d\n", sizeof(a[0] + 1));       //4
  printf("%d\n", sizeof(*(a[0] + 1)));      //5
  printf("%d\n", sizeof(a + 1));          //6
  printf("%d\n", sizeof(*(a + 1)));       //7
  printf("%d\n", sizeof(&a[0] + 1));        //8
  printf("%d\n", sizeof(*(&a[0] + 1)));     //9
  printf("%d\n", sizeof(*a));           //10
  printf("%d\n", sizeof(a[3]));         //11
  return 0;
}


答案:



1.  48字节    a单独出现在sizeof括号中,表示计算整个数组的地址,数组每个元素是整形,4*3*4=48字节
2.  4字节   a[0][0]计算数组首元素的地址,是一个整形占四个字节.
3.  16字节    a[0]是第一行的数组名,数组名单独放在sizeof中,表示第一行的地址,4*4=16字节
4.  4/8字节   a[0]不是单独出现,也没有&(取地址),表示的是第一行第一个元素即a[0][0],后面+1表示第一行第二个元素的地址.
5.  4字节   因为a[0]+1表示第一行第二个元素的地址,则解引用得到的是第一行第二个元素.该元素是整形.
6.  4/8字节   a是数组名,表示二维数组的第一行,a的类型是int(*)[4],那么+1会跳过一行,即表示第二行的地址,地址4/.8字节.
7.  16字节    *(a+1)等价于a[0],第二行的数组名单独放在sizeof里面,表示得到第二行所有元素.
8.  4/8字节    (&a[0] + 1)),&a[0]表示第一行的地址,+1表示第二行的地址,地址是4/8字节
9.  16字节    对第二行解引用,等价于a[1],数组名单独放进sizeof,表示这一行的大小.
10. 16字节    a是表示第一行的地址,*a等价于a[0],类型是int(*)[4].
11. 16字节    a[3]虽然表示第四行数组名,二维数组只有3行,但是sizeof并没有访问第四行,而是计算第四行类型大小,int(*)[4].


希望通过这些练习能更加清楚的指针,通过sizeof和strlen函数里面的参数,指针的来回变化会加深对指针的理解.

目录
相关文章
|
7月前
|
编译器 C语言
sizeof,sizeof与strlen的区别
sizeof,sizeof与strlen的区别
67 0
sizeof,sizeof与strlen的区别
|
6月前
|
C语言
sizeof与strlen的使用及其区别
sizeof与strlen的使用及其区别
sizeof与strlen的使用及其区别
|
2月前
|
编译器 C++
sizeof 和 strlen 的区别
`sizeof` 和 `strlen` 是 C 和 C++ 中常用的运算符/函数,功能和用途不同
72 11
|
7月前
|
存储 编译器
strlen()和sizeof()的区别
strlen()和sizeof()的区别
57 0
strlen和sizeof详解
strlen和sizeof详解
87 0
|
C语言
strlen和sizeof的区别
strlen和sizeof的区别
91 0
strlen与sizeof的区别
strlen与sizeof的区别
91 0
sizeof和strlen的对比
sizeof和strlen的对比
54 0
sizeof与strlen区别
sizeof是关键字,参数可以是各种数据(包括函数,类型,对象,数组,指针……)用于计算数据所占字节大小 strlen是函数,参数类型必须是字符型指针(char *),用于计算字符串,从字符串的第一个地址开始遍历,直到遇到‘\0’停止
87 0
|
存储 编译器 C++
sizeof 与strlen的区别与联系
sizeof 与strlen的区别与联系
120 0
sizeof 与strlen的区别与联系