在C语言开发中,sizeof()是一个什么样的存在呢?有多少人认为它是个函数?或者曾经是否也认为它是函数呢?

今天我们介绍下sizeof()的同时,并通过它延伸展开,来聊一聊一些C语言的基础知识。

1、sizeof是什么?

sizeof是C语言中的关键字,也可以认为是一种运算符。 是一个判断数据类型或者表达式长度的运算符。

2、sizeof的使用及C语言知识延伸

通过实际的代码编写并使用printf();函数来输出要展示的结果,向大家详细进行阐述。(编辑编译环境 :C FREE-5)

1)测试基本数据类型的长度

#include <stdio.h>
#define uint8_t unsigned char
#define uint32_t unsigned int
int main(void)
{
//基本数据类型
printf("uint8_t length = %d\r\n",sizeof(uint8_t));
printf("\r\n");
printf("uint32_t length = %d\r\n",sizeof(uint32_t));
}

通过编译输出如下内容:

可以看出uint8_t 类型占用1个字节 。uint32_t 类型占用4个字节。没毛病,咱们继续。

2)测试普通变量的数据长度

#include <stdio.h>
#define uint8_t unsigned char
#define uint32_t unsigned intuint32_t Var ;//普通变量 int main(void)
{
//普通变量
printf("Var length = %d\r\n",sizeof(Var));
printf("\r\n");
}

通过编译输出如下内容:

我在代码中定义了一个uint32_t 类型的变量,毫无悬念,这个变量也占4个字节。继续往下看:

3)测试数组的数据长度

#include <stdio.h>
#define uint8_t unsigned char
#define uint32_t unsigned intuint32_t Array_A[10];//普通数组 int main(void)
{
//普通数组
printf("Array_A length = %d\r\n",sizeof(Array_A));
printf("\r\n");
printf("Array_A[10] length = %d\r\n",sizeof(Array_A[10]));
printf("\r\n");
printf("&Array_A length = %d\r\n",sizeof(&Array_A));
printf("\r\n");
printf("&Array_A[0] length = %d\r\n",sizeof(&Array_A[0]));
printf("\r\n");}

通过编译输出如下内容:

这里我重点说下,通过测试我们可以看到:

sizeof()的括号中,直接写数组的名字,则求的是整个数组所占用的总字节数。

sizeof()的括号中,写入Array_A[10],居然也可以等于4,因为Array_A[10]这个数组定义的是uint32类型的,从Array_A[0]到Array_A[9],所以任何一个元素都是4字节,但是Array_A[10]这个元素下标到10了,明显溢出。软件居然没有报错,甚至都没有警告。这个地方要注意一下。

sizeof()的括号中,写入&Array_A,代表数组首地址,占用4个字节。

sizeof()的括号中,写入&Array_A[0],代表数组首元素地址,也占用占用4个字节。

4)测试指针变量的数据长度

#include <stdio.h>
#define uint8_t unsigned char
#define uint32_t unsigned intuint32_t Var ;//普通变量
uint32_t *p = &Var;//指针 int main(void)
{
//指针
printf("p length = %d\r\n",sizeof(&p));
printf("\r\n");
printf("*p length = %d\r\n",sizeof(*p));
printf(" \r\n");
}

通过编译输出如下内容:

为什么&p的长度和*p的长度都是4个字节呢?

“printf(“p length = %d\r\n”,sizeof(&p));”这一条输出指针地址的长度。是4个字节。

“printf("*p length = %d\r\n",sizeof(*p));”这一条输出的是指针所指向变量类型的长度。也就是这句话:“uint32 *p = &Var" 从上面我们可以得知Var的数据类型就是uint32_t,也是4个字节。

好,下面我们来稍微做个更改:

#include <stdio.h>
#define uint8_t unsigned char
#define uint32_t unsigned intuint8_t Var ;//普通变量
uint8_t *p = &Var;//指针
int main(void)
{
//指针
printf("p length = %d\r\n",sizeof(&p));
printf("\r\n");
printf("*p length = %d\r\n",sizeof(*p));
printf("\r\n");
}

这这里我把 Var的数据类型由uint32_t 改为uint8_t ,把uint32_t *p 改为 uint8_t *p。然后大家可以思考一下:

“printf(“p length = %d\r\n”,sizeof(&p)); “输出多少?

“printf("*p length = %d\r\n",sizeof(*p));”输出多少?

下面我们来看结果:

由编译结果可以看到,&p的长度是4。是4个字节吗?和你想得一样吗?这个结果对吗?我们不是把uint32_t *p 改为 uint8_t *p了吗?不应该是1个字节吗?

这里引伸出一个重要的结论: *号前面的数据类型只是表示指针所指向的内存里数据的类型,并不代表指针地址的类型。它和指针的大小无关,并不会对指针的长度产生影响。指针的地址大小是和所处的编译环境有关系。

p的长度,这里编译结构现实变成了1个字节。因为指针指向的数据类型改成了uint8_t ,也就是Var变量变成了1.因为Var 的数据类型是 uint8_t ,所以对应的p前面的数据类型也要是uint8_t, 这样才能保持一致,否则编译器会提示不兼容。这也从侧面应证了: *号前面的数据类型只是表示指针所指向的内存里数据的类型,并不代表指针地址的类型。”

这个内容就说到这里,感兴趣的朋友可以在自己的编译环境上测试一下。

5)测试构造数据类型的数据长度

#include <stdio.h>
#define uint8_t unsigned char
#define uint32_t unsigned inttypedef struct
{uint8_t Var1;
uint8_t Var2;
uint32_t Var3;
}
ST_Test; typedef union
{ST_Test st_test;
uint8_t Array_B[10];
}
UN_Test;int main(void)
{
//构造数据类型
printf("ST_Test length = %d\r\n",sizeof(ST_Test));
printf("\r\n");
printf("UN_Test length= %d\r\n",sizeof(UN_Test));
printf("\r\n");
}

通过编译输出如下内容:

我们接着来看,首先第一个构造的数据类型是一个结构体:根据编译输出的提示,该结构体占用的长度为8个字节。为什么是8个字节,不是6个字节?在结构体中,数据长度不是单纯的相加,而是会涉及到字节对齐的问题。网上有很多这方面的资料,这里不深入展开了。

第二个构造的数据类型是共用体。共用体和结构体的最大区别就是内部的各个成员变量共用一块内存。内存大小取决于成员变量中最大的成员。那按道理这个共用体的长度应该是10呀。因为共用体内的两个成员,结构体成员是8个字节,Array_B[10]是10个字节。为什么是12呢?同理,也是字节对齐的原因。

然后接着再做一个延伸:


```c
#include <stdio.h>
#define uint8_t unsigned char
#define uint32_t unsigned inttypedef struct
{
uint8_t Var1;
uint8_t Var2;
uint32_t Var3;
}
ST_Test;#pragma pack(1)
typedef union
{ST_Test st_test;
uint8_t Array_B[10];
}
UN_Test;
#pragma pack()int main(void)
{
//构造数据类型
printf("ST_Test length = %d\r\n",sizeof(ST_Test));
printf("\r\n");
printf("UN_Test length= %d\r\n",sizeof(UN_Test));
printf("\r\n");
}

编译输出为:

通过使共用体一字节对齐后,可以看到它的数据类型占用的内存大小就变成了10个字节。

共用体可以用来测试数据存储模式是大端模式还是小端模式。限于篇幅,这里就不展开了。感兴趣的朋友自行百度。

这就是今天要分享的内容,比较基础。给不清楚这块知识的朋友提供个思路。明白了这块的朋友也可以借此机会复习一下。说得不对的地方,还请各位朋友提出宝贵意见。

欢迎关注微信公众号:电子工程师联盟。一起学习,共同进步!

由sizeof 这个“管”,窥一窥C语言这只“豹”相关推荐

  1. c语言sizeof怎么计算字节数,理解c语言的sizeof

    c语言有很多用起来需要特别注意的地方,我们(计算机学习微信公众号:jsj_xx)以后会分析其中有使用价值的点.今天我们一起看看sizeof.c语言通过类型长度来达到指针的灵活性,我们觉得,某种意义上讲 ...

  2. 面试准备每日五题:C++(一)——变量定义声明、#ifdef #else、结构体赋值、sizeof strlen、C和C++的static

    文章目录 1 变量的声明和定义有什么区别? 2 简述#ifdef.#else.#endif和#ifndef的作用 3 结构体可以直接赋值吗? 4 sizeof 和strlen 的区别 5 C 语言的关 ...

  3. c语言sizeof啥作用,C语言中sizeof什么意思

    C语言中"SIZEOF(INT)"是什么意思?有什么作用? C语言中,sizeof是一个? sizeof是C语言中保留关键字,也可以认为是一种运算符,单目运算符:sizeof是计算 ...

  4. 详解C语言中sizeof的使用

    目录 一.sizeof是什么? 二.sizeof的使用 三. 在字符串数组中sizeof与strlen的区别 四.总结 一.sizeof是什么? 在 C /C++语言中,sizeof() 是一个判断数 ...

  5. c语言获取结构体大小sizeof,C语言sizeof求结构体数组长度

    C语言sizeof求结构体数组长度 C语言sizeof求结构体数组长度 #include typedef struct ss{ char a;//偏移量为0,大小为1,0能被1整除,=1 short ...

  6. C语言sizeof()中的赋值问题

    C语言sizeof()中的赋值问题 #include <stdio.h>int main() {int a = 0;int b = sizeof(a = 123);printf(" ...

  7. c语言中sizeof函数的作用是,c语言中sizeof函数的用法

    C语言sizeof函数如何使用? 怎样利用sizeofCSS布局HTML小编今天和大家分享各种数据类型占用的字节数? (1)sizeof不是函数,它只是一个操作符(operator). (2)size ...

  8. c语言sizeof返回数据类型,sizeof函数返回值类型

    #include int main(void) { printf("type int has a size of (1)sizeof不是函数,它只是一个操作符(operator). (2)s ...

  9. sizeof的使用(指针和数组地址的区别)

    sizeof并不是函数,是C语言中的关键字,使用sizeof可以得到变量的类型所占的空间大小. 1.对数组使用sizeof int a[5] = { 1,2,3,4,5 };printf(" ...

最新文章

  1. 韦东山网课https://edu.csdn.net/course/play/207/1117
  2. 音视频即时通讯的介绍与前景
  3. nyoj99(欧拉路)
  4. React Native开发指南-在原生和React Native间通信
  5. Python学习笔记(四十)— 内置模块(9)HTMLParser
  6. 26. Location assign() 方法
  7. 图像放缩中最近邻插值和双线性插值的基本原理
  8. 35岁-59岁-人生的二个世界
  9. [RK3288][Android6.0] 如何配置MIPI DSI Clock和PCLK
  10. 使用perl统计单词(字母)
  11. 中美线径对照表_美国线规对照表
  12. 现代控制理论课程实验三:一阶倒立摆的LQR控制器设计
  13. com.android.yf.idp,QQ轻聊版-com.tencent.qqlite_v3.3.0_apkpure.apk
  14. [翻译+分析总结] nnU-Net for Brain Tumor Segmentation
  15. Adobe Illustrator【印前角线X2.0】脚本源码
  16. 如何让ARM板开机启动Qt
  17. 常用单片机模块(四)
  18. [ABAP] PBOM历史版本函数展开 CSAP_MAT_BOM_READ
  19. 微信分享自定义图文链接
  20. 简单面试题,但是容易忘记

热门文章

  1. Ubuntu18.04 同一个程序显示两个图标,收藏夹图标不合并问题解决
  2. 手游开发者大会交流OGEngine新版本发布
  3. 管理的角度分析:团队建设、团队管理、团队文化、沟通与辅导、招聘与解雇等
  4. Sprite Kit 移动精灵
  5. Python-with open() as f写入
  6. vaild-palindrome
  7. php检索本地文件,神器:不仅秒搜本地文件,还能1秒在线检索文献!
  8. 联想笔记本上Ubuntu无线网卡问题
  9. WPS 操作之在指定页插入页码
  10. 安装Tomcat 9