实战例子1

经过这些例子,可以加深对sizeof,数组,数组名,取数组地址,地址加一,指针,指针加一的理解,一定要特别注意数组名在不同场景下的含义

一:数组名是数组首元素的地址

但是有2个例外

  1. sizeof(数组名):数组名表示整个数组,计算的是整个数组的大小,单位是字节
  2. &数组名:数组名表示整个数组,取出的是整个数组的地址,如&arr,当&arr+1时,打印的是相隔arr数组大小的地址

除此之外,所有的数组名都是数组首元素的地址

二:指针的大小:32位平台下都是4字节,64位平台下都是8字节

三: strlen -函数:求字符串长度的,找’\0’之前出现的字符个数;sizeof -操作符:算变量/类型所占内存大小,单位是字节

strlen函数原型:size_t strlen ( const char * str ); 参数是指向字符类型的指针

记住上面的规则后,让我们开始吧~

int a[ ] = { 1,2,3,4 }; //4*4=16

printf( "%d\n", sizeof(a)) ;   //16    整个数组的大小是16printf("%d\n", sizeof(a + 0)); /*4或8   a + 0是第一个元素的地址,sizeof(a + 0)计算的是地址的大小,sizeof后面跟的不是单                                       个a,就不是一整个数组*/printf ("%d\n", sizeof(*a));   //4     *a是数组的第一个元素,sizeof(*a)计算的是第一个元素的大小printf ("%d\n", sizeof(a + 1));    //4或8   a + 1是第二个元素的地址,sizeof(a+1)计算的地址的大小printf ( "%d\n", sizeof(a[1]));    //4     计算的是第二个元素的大小
printf ("%d\n", sizeof(&a));       //4/8       &a取出的是整个数组的地址,但也是地址,计算的是一个地址的大小printf ( "%d\n", sizeof(*&a));       //16        先取出整个数组的地址,再解引用,得到的还是整个数组,计算的数组的大小printf ("%d\n", sizeof(&a + 1));  /*4/8       &a得到一整个数组的地址,+1后跳过一整个数组,是数组最后一个元素后面的                                              空间的地址*/
printf ( "%d\n", sizeof(&a[0]));  //4/8       第一个元素的地址printf ( "%d\n", sizeof(&a[0] + 1)); //4/8    第二个元素的地址

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

printf ("%d\n", sizeof(arr));      //6         整个数组的大小为6printf ("%d\n", sizeof(arr + 0));   //4/8       首元素地址+0还是地址printf ("%d\n", sizeof(*arr));        //1     首元素地址解引用得到字符a,大小是1printf ("%d\n", sizeof(arr[1]));    //1         第二个数组元素的大小printf ("%d\n", sizeof(&arr));      //4/8       一整个数组的地址printf ("%d\n", sizeof(&arr + 1));   //4/8       跳过一整个数组后的地址printf ("%d\n", sizeof(&arr[0]+ 1));  //4/8   &arr[0]是第一个元素的地址,+1后是第二个元素的地址
printf("%d\n",strlen(arr));        //随机值,从首元素地址开始找,strlen会一直找到'\0'为止printf ("%d\n", strlen(arr + 0));   //随机值,首元素地址加0还是首元素地址printf ("%d\n", strlen(*arr)); /*error,首元素地址解引用得到的是字符'a',ASCII码值是97,而strlen函数的参数是(char*                                    str),接收的是地址*/printf ("%d\n", strlen(arr[1])); //error,同理,把字符'b'传过去也是出错printf ("%d\n", strlen(&arr));        /*随机值,取一整个数组的地址传给strlen函数时,也会被强制类型转换为char*类型,也是从首                                  元素地址开始找起*/printf ("%d\n", strlen(&arr + 1)); /*随机值-6,取一整个数组地址后+1,就跳到了该数组最后一个元素的后一个地址,相比从首元素开始找,此时直接跳过了数组的长度,所以要-6,但找的结果仍然是随机值*/printf ("%d\n", strlen(&arr[0]+ 1));    /*随机值-1,取首元素的地址后+1,得到第二个元素的地址,跳过了一个元素长度,所以要-1;*/

char arr[ ]= “abcdef” ;

内存存放形式:[a b c d e f \0]

printf ("%d\n", sizeof(arr));      //7     双引号""默认在最后加上'\0',sizeof会把'\0'也算上printf ("%d\n", sizeof(arr + 0));  //4/8   首元素地址+0还是地址printf ("%d\n", sizeof(*arr));        //1     首元素地址解引用得到字符'a','a'的大小printf ("%d\n", sizeof(arr[1])); //1     字符'b'的大小printf ("%d\n", sizeof(&arr));      //4/8       取一整个数组的地址printf ("%d\n", sizeof(&arr + 1));  //4/8       跳过一整个数组后还是地址printf ("%d\n", sizeof(&arr[0]+ 1));     //4/8       第二个元素的地址
printf ("%d\n", strlen(arr));      //6     strlen从首元素开始向后检索字符,遇到'\0'就停下,不包括'\0'printf ("%d\n", strlen(arr + 0));  //6     首元素地址+0还是从首元素开始检索printf ("%d\n", strlen(*arr));      //errorprintf ("%d\n", strlen(arr[1]));   //errorprintf ("%d\n", strlen(&arr));     //6       一整个数组的地址,传给strlen也是从首地址开始printf ("%d\n", strlen(&arr + 1)); //随机值    取出一整个数组的地址后+1,跳过一整个数组,跳到'\0'的后一个地址,开始检索时不知什么时候会找到'\0'printf ("%d\n", strlen(&arr[0] + 1));    //5 从第二个元素开始找

实战例子2

char* p = “abcdef” ;

指针p指向一块连续的常量空间,[a b c d e f \0]

printf ("%d\n", sizeof(p));            //4/8       求的是p指针的大小printf ("%d\n", sizeof(p + 1));     //4/8       p指向的是字符a的地址,+1就指向字符b的地址,终究还是地址printf ("%d\n", sizeof(*p));     //1         p指针解引用得到字符a,大小为1printf ("%d\n", sizeof(p[0]));     //1         p[0] == *(p+0),得到字符a,大小为1printf ("%d\n", sizeof(&p));       //4/8       取指针p自己的地址printf("%d\n", sizeof(&p + 1));     //4/8       跳过一个p的地址,即指针p的后一块地址空间printf("%d\n", sizeof(&p[0] + 1));   //4/8       &p[0]得到第一个元素的地址,+1得到第二个元素的地址
printf("%d \n", strlen(p));            //6 printf ("%d \n", strlen(p + 1)); //5     p指向第一个字符地址,+1后指向第二个字符地址printf ("%d\n", strlen(*p));       //errorprintf ("%d\n", strlen(p[0]));     //errorprintf ("%d\n", strlen (&p));      //随机值   取p指针自身的地址,因为p占4/8个字节,从首字节开始找,不知何时才找到'\0'printf ("%d \n", strlen (&p + 1));        //随机值   从p指针最后一个字节的后一个地址开始找,也不知何时找到'\0',因为不确定p指针中有没有'\0',所以这个随机值并没有-1,跟上一个随机值没有联系printf ("%d\n", strlen ( &p[0] + 1));   //5     从第二个元素开始找

int a[ 3] [4]={ 0 };

a[0]:第一行一维数组的数组名

a[1]:第二行一维数组的数组名

a[2]:第三行一维数组的数组名

printf ("%d\n", sizeof(a)) ;       //48    3*4*sizeof(int),sizeof里是单独的二维数组名,就表示一整个二维数组的大小printf ("%d\n", sizeof(a[0][0]));     //4  第一行第一个元素值,整型元素大小是4printf ("%d\n", sizeof(a[0]));      //16    a[0]表示整个第一行,数组名a[0]单独放在sizeof内部,sizeof(a[0])计算的就是第一行一维数组的大小!printf ("%d\n", sizeof(a[0]+ 1));      //4/8       a[0]作为数组名并没有单独出现在sizeof内,也没取地址,所以a[0]就是第一行第一个元素的地址,a[0]+1就是第一行第二个元素的地址printf ("%d\n", sizeof(*(a[0] + 1)));        //4     第一行第二个元素值printf ("%d\n", sizeof(a + 1)) ;        //4/8       a是二维数组的数组名,并没有取地址,也没有单独放在sizeof内,所以表示的是二维数组首元素的地址,即第一行的地址,a+1就是二维数组第二行的地址printf ("%d\n", sizeof(*(a + 1)));      //16        因为*(a+1) == a[1],a[1]表示的是第二行的地址,由因为sizeof(a[1])是单独放在sizeof内部的,表示第二行一整个一维数组的地址,所以求的是一整个一位数组的大小printf ("%d\n", sizeof(&a[0] + 1));      //4/8   &a[0]+1 == a+1  a[0]是第一行的数组名,&a[0]取出的是第一行整个一维数组的地址,+1后就是第二行整个一维数组的地址printf ("%d\n", sizeof(*(&a[0]+ 1))); //16    *(&a[0]+1) == *(a+1)    &a[0]+1得到的就是第二行整个一维数组的地址,解引用得到一整个第二行一维数组,所以大小是16printf ("%d\n", sizeof(*a));       //16        *a == *(a+0) == a[0],a是二维数组的数组名,并没有取地址,也没有单独放在sizeof内,表示第一行的地址,等于第一行数组名单独放到sizeof中,相当于求第一行整个一维数组的大小printf ("%d\n", sizeof(a[3]));      //16        a[3]的类型是 int [4],其实是第四行的数组名(如果有的话),此时sizeof并不会真正去访问a[3]的地址,只是根据其类型计算出大小,sizeof()内部的表达式是不算的!   比如表达式:3+5   具有:1.值属性 -> 8 2.类型属性 -> int,sizeof就是推测出类型属性从而计算大小的

C语言sizeof的实战例子相关推荐

  1. C语言 sizeof 函数 - C语言零基础入门教程

    目录 一.sizeof 函数简介 二.sizeof 函数实战 三.猜你喜欢 零基础 C/C++ 学习路线推荐 : C/C++ 学习目录 >> C 语言基础入门 一.sizeof 函数简介 ...

  2. C语言 sizeof 和 strlen 函数区别 - C语言零基础入门教程

    目录 一.sizeof 函数与 strlen 函数区别 1.获取字符串长度 – 针对字符串 2.获取指针/数组长度 – 针对指针/数组 3.sizeof 获取内存大小 4.经典案例 二.猜你喜欢 零基 ...

  3. Go语言入门到实战——14.Go语言的协程机制以及并发机制

    Go语言入门到实战--00主目录 在上一讲中我们学习了Go语言的包的知识已经依赖管理. 协程(groutine)是一种更加轻量级的线程(thread). 一.协程与线程得到比较 1.对于java而言, ...

  4. C语言sizeof的用法及注意事项

    C语言sizeof的用法及注意事项 求普通变量的大小 #include <stdio.h> int main() {int a = 5;printf ("%d\n", ...

  5. 编程思想之c语言课程设计--管理系统例子

    文章目录 前言 思路--用计算机"模拟世界" c语言 数据结构 算法 总结 例子--学生管理系统(控制台) 考虑 需求 分析 1.提供菜单 2.接收命令 3.添加学生信息 4.打印 ...

  6. R语言单变量分析实战:汇总统计(Summary Statistics)、频率表(Frequency Table)、图表(charts: boxplot、histogram、density)

    R语言单变量分析实战:汇总统计(Summary Statistics).频率表(Frequency Table).图表(charts: boxplot.histogram.density) 目录

  7. R语言Box-Cox变换实战(Box-Cox Transformation):将非正态分布数据转换为正态分布数据、计算最佳λ、变换后构建模型

    R语言Box-Cox变换实战(Box-Cox Transformation):将非正态分布数据转换为正态分布数据.计算最佳λ.变换后构建模型 目录

  8. R语言Goldfeld-Quandt检验实战:检验回归模型中是否存在异方差性(heteroscedasticity)、发生了异常差(heteroscedasticity)问题如何解决

    R语言Goldfeld-Quandt检验实战:检验回归模型中是否存在异方差性(heteroscedasticity).发生了异常差(heteroscedasticity)问题如何解决 目录

  9. R语言NaN函数实战(计数、替换、删除)

    R语言NaN函数实战(计数.替换.删除) 目录 R语言NaN函数实战(计数.替换.删除) #NA.NaN.Null区别?

最新文章

  1. 从hook007学习dll劫持自启动方式
  2. 从零入门 FreeRTOS操作系统之信号量
  3. Cannot add or update a child row: a foreign key constraint fails (`university`.`instructor`, CONSTRA
  4. mapreduce简单的gzip压缩
  5. mysql中的正向工程_Hibernate系列之正向工程
  6. win10偶然无法使用任务栏的问题解决办法
  7. mysql中的事务_mysql中的事务,你理解嘛?
  8. linux tcp自动重连,LabVIEW TCP/IP 断开重连问题
  9. [poj] 1236 networks of schools
  10. 31.go 函数式编程
  11. 1.ESP32c3 移植lvgl核心组件教程
  12. windows系统搭建图像识别开发环境
  13. WinRAR下载官方免费版
  14. 电子信息类包含计算机科学与技术么,电子信息类和计算机类有什么区别
  15. Rimworld Mod制作教程2 创建数据定义
  16. 基于Python的微信好友男女比例,区域排名,签名情感分析
  17. Windows 10 Version 2004 新功能盘点
  18. robocup3d 发布比赛版本
  19. 张丽俊最新演讲:要像竹子一样扎根,你终会一飞冲天
  20. Dijkstra算法讲解(通过边实现松弛)

热门文章

  1. 快速判断一个数是不是素数(质数)
  2. Android事件的前世今生:可能是全宇宙讲得最通俗易懂的一篇
  3. 爬取steam上热门游戏的价格,网址,评价数据
  4. matlab的巴特沃斯滤波器,巴特沃斯滤波器滤波
  5. 运动蓝牙耳机排名前十的品牌,推荐几款好用的运动蓝牙耳机
  6. 迅雷2021校招数据分析笔试题 B卷
  7. 即兴演讲的三定——主题、观点和框架
  8. C语言技巧一 全局变量定义
  9. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  10. Quotable Quotes by Reader's Digest