C语言数据类型与sizeof关键字

目录
  • 一、前言
  • 二、数据类型
    • 1、数据类型有哪些
    • 2、为什么要有数据类型
    • 3、如何看待数据类型
  • 三、sizeof – 计算不同类型变量开辟空间的大小
    • 1、内置类型开辟的空间大小
    • 2、自定义类型开辟的空间大小
    • 3、指针类型开辟的空间大小
    • 4、空类型开辟的空间大小
  • 四、对sizeof 的进一步理解
    • 1、sizeof 为什么不是函数
    • 2、sizeof 的其他使用

一、前言

大家好,欢迎来到C语言深度解析专栏—C语言关键字详解第三篇,在本篇中我们将会介绍C语言当中的数据类型,并由此引出C语言当中的另外一个重要的关键字 — sizeof .

第一篇:C语言 auto和register关键字

第二篇:全面了解C语言 static 关键字

二、数据类型

1、数据类型有哪些

C语言的数据类型包括基本类型(内置类型)、构造类型(自定义类型)、指针类型以及空类型

2、为什么要有数据类型

为什么要有内置类型

我们日常生活中会遇到各种各样的场景,而不同的场景需要不同数据来表示,比如我们聚餐的人数、天气的温度、海拔的高度等事情通常用整数来描述,而像人的身高、广播的频率、商品的价格则通常用小数表示,又比如我们的车牌号、楼栋的命名、服装的尺码则需要要用字母来表示;C语言作为第一门高级程序设计语言,为了能准确描述我们生活中各种各样的场景,就有了整形、浮点型、字符型这些内置类型。

为什么要有自定义类型

我们以自定义类型中的数组类型和结构体类型举例:
数组类型:我们生活中会碰到许多相同类型的集合,比如一个学校学生的学号,每一个学生的学号都是整形,那么为了表示所有学生的学号,就势必要定义几千个整形,显然,那样太麻烦了,于是就产生了数组类型,一个数组里面的每个元素的类型都是相同的,我们在定义一个学校学生的学号时,只需要定义一个有几千个元素大小的数组即可,而不必去慢慢定义一千个整形
结构体类型:我们生活中所要描述的对象常常是复杂数据类型的集合,拿人来说,一个人有姓名、性别、身高、体重、年龄等等,这些数据类型都是不同的,那么为了能够系统的描述一个人的属性,就产生了结构体类型,它把一个人不同类型的数据都集中到一个新的类型当中,使对象描述和使用更加方便。

3、如何看待数据类型

从前面的博客中我们知道,定义变量的本质是在内存中开辟一块空间,用来存放数据,而今天我们知道不同的变量是需要定义为不同的类型的,把二者结合起来,我们就不难得出:类型决定的是变量开辟空间的大小。
这时有两个疑问点,第一、为什么要根据类型来开辟空间,我们直接开辟一块空间,将内存整体使用不好吗?答案是:不好。

原因主要有两点:

1、在任何时刻,你的电脑都不是只在运行你目前所使用的那个程序,还有其他许多的程序也在同时运行,如果把整块都分配给了你目前运行的程序,其他程序就崩溃了。
2、即使把整块内存都分配给你,你也不能保证在任何时刻都对该内存块全部都用完,这样就会导致内存的浪费。
第二、我们使用部分内存,使用多少由什么决定的?答案是:是由你的场景决定,你的计算场景,决定了你使用什么类型的变量进行计算。你所使用的类型,决定了你开辟多少字节的空间大小。这也是为什么C语言要有这么多的数据类型,就是为了满足不同的计算场景。
最后,那么不同的数据类型到底在内存开辟多少空间呢?这就需要使用我们的关键字 – sizeof 来计算了。

三、sizeof – 计算不同类型变量开辟空间的大小

1、内置类型开辟的空间大小

`#include<stdio.h>
int main()
{
    printf("%d\n", sizeof(char));       //1
    printf("%d\n", sizeof(short));      //2
    printf("%d\n", sizeof(int));        //4
    printf("%d\n", sizeof(long));       //4
    printf("%d\n", sizeof(long long));  //8
    printf("%d\n", sizeof(float));      //4
    printf("%d\n", sizeof(double));     //8
}`

2、自定义类型开辟的空间大小

数组大小

#include<stdio.h>
int main()
{
    int arr1[10] = { 0 };       //40
    char arr2[10] = { 0 };      //10
    long int arr3[10] = { 0 };  //40
    long long arr4[10] = { 0 }; //80
    float arr5[10] = { 0 };     //40
    double arr6[10] = { 0 };    //80
    printf("%d\n", sizeof(arr1));
    printf("%d\n", sizeof(arr2));
    printf("%d\n", sizeof(arr3));
    printf("%d\n", sizeof(arr4));
    printf("%d\n", sizeof(arr5));
    printf("%d\n", sizeof(arr6));
    return 0;
}

从上面的结果我们很容易得出:数组的大小 = 数组元素的类型乘以元素个数

其他自定义类型的大小

#include<stdio.h>
struct Test1{
    int a;
    char b;
    float c;
    double d;
};
union Test2{
    int m;
    char n;
};
enum Test3 {
    monday,
    tuesday,
    wednesday,
    thursday,
    frifay
};
int main()
{
    struct Test1 test1 = { 0 };
    union Test2 test2 = { 0 };
    enum Test3 test3;
    printf("%d\n", sizeof(test1));   //24
    printf("%d\n", sizeof(test2));   //4
    printf("%d\n", sizeof(test3));   //4
}

想必上面的结果与一些小伙伴心中的结果有所不同,确实,结构体、联合体、枚举这些自定义类型的大小和数组大小的求法是不相同的,其具体的求法涉及内存对齐、大小端、内存分配等相关知识,这些知识比较复杂,我会放在自定义类型详解模块中为大家讲解,现在大家不用去深究。

3、指针类型开辟的空间大小

大家可以看到,我们上面不管指针的类型是什么(整形、字符型、浮点型、数组型),指针的大小始终是四个字节或者八个字节(第一张图X86表示32位平台,结果为4,第二张图X64表示64位平台,结果为8),所以结论就是:指针在32位平台下是4个字节,在64位平台下是8个字节。(至于为什么是这样,这涉及到内存编址、地址线等相关知识,这一部分我会放在指针那里来详细讲解,现在大家只需要记住这个结论即可)
注:第二张图有警告是因为我的电脑是32位平台的,强制转成64位会发生大小不匹配的问题。

4、空类型开辟的空间大小

我们可以看到虽然这里编译器报错了,但它仍然打印出来了void的大小:0个字节
注:void类型的大小为0个字节,这仅仅是在visual studio这个编译器下运行的结果,但是,这个结果在不同的编环境下跑出来可能不同,就比如在Linux环境下,void类型的大小就为1,(由于水平的限制,这里暂时不能为大家演示);而导致这两者之间有差异的根本原因是不同编译环境对C语言的支持程度不同。

四、对sizeof 的进一步理解

1、sizeof 为什么不是函数

从上面我们可以看到,我们可以用 sizeof(a) 和 sizeof(int) 求一个整形的大小,这种方式也是大家所熟悉的,但是我们发现直接用
sizeof a 也能求出a的大小,而不需要圆括号,所以说,sizeof 是关键字(操作符)但是不是函数,因为函数参数需要用 () 起来才能正常使用。
注:sizeof int 报错是因为 sizeof 和 int 都是关键字,而不能用一个关键字去求另一个关键字的大小

2、sizeof 的其他使用

这里我们定义了一个整型变量 a 和 指针变量 p ,以及数组 arr,可以看到 a 的大小为 4,arr 的大小为40,这些我们都理解,
那么剩下的sizeof § 、sizeof(&arr) 、sizeof(arr) / sizeof(arr[0]) 是什么意思呢?下面为大家解释(涉及指针相关知识)

p 是一个指针变量,里面存放的是 a 的地址,arr数组名表示arr数组首元素的地址(记忆),&arr 表示取出整个数组的地址,相当于一个数组指针,所以sizeof§ 和 sizeof(&arr) 都是求的指针的大小,而在上面我们知道,指针在32位平台下是4个字节,所以这里结果为4。
最后,sizeof(arr) 求整个数组的大小,sizeof(arr[0]) 求第一个元素的大小,所以二者相除得到的是数组的元素个数10。
注:这里用sizeof(arr[0]) 来求一个数组元素的大小,而不是用arr[1] 、arr[2] 是因为我们不知道数组有几个元素,所以可能arr[1] 、arr[2] 根本不存在,但是只要定义了数组,那么arr[0] 就是一定是存在的,也就是说,这样做是为了安全。

到此这篇关于C语言数据类型与sizeof关键字的文章就介绍到这了,更多相关C语言 sizeof关键字内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C语言中sizeof函数踩过的坑总结

    sizeof很简单,但是却很容易令人踩坑. 正文 先来看这样一段代码 int main() { int i=2; printf("%d\n",sizeof(i++)); printf("%d\n",i); return 0; } 非常简单的一段代码 当时我认为答案应该是 4 3 可是结果却是出乎我的意料了 这是为什么呢? 下面来仔细说一下 通过调试观察虽然确实有i++这么一句代码,但是却没有实现.说到这里很多人可能犯了和我一样的错误,认为sizeof是一个函数. 其

  • C语言中typedef的用法以及#define区别详解

    目录 1.简洁定义 2.为已有类型起别名 为字符数组起别名 为指针起别名 3.typedef 和 #define 的区别 总结 1.简洁定义 C语言允许为一个数据类型起一个新的别名,就像给人起"绰号"一样.而编程中起别名,是为了编程人员编程方便,例如: 定义如下结构体 struct stu { int ID; char name[20]; float score[3]; char *data; }; 要想定义一个结构体变量就得这样写: struct stu Marry://Marry是

  • c语言中enum类型的用法案例讲解

    11.10 枚举类型 在实际问题中,有些变量的取值被限定在一个有限的范围内.例如,一个星期内只有七天,一年只有十二个月,一个班每周有六门课程等等.如果把这些量说明为整型,字符型或其它类型显然是不妥当的.为此,C语言提供了一种称为"枚举"的类型.在"枚举"类型的定义中列举出所有可能的取值,被说明为该"枚举"类型的变量取值不能超过定义的范围. 应该说明的是,枚举类型是一种基本数据类型,而不是一种构造类型,因为它不能再分解为任何基本类型. 11.10.

  • C语言数据类型枚举enum全面详解示例教程

    目录 一.枚举类型的定义 二.枚举类型的使用 2.1创建变量 2.2一些优点 总结 一.枚举类型的定义 enum Day//enum Day是一种类型 { Mon,//周一到周日这些叫枚举的可能取值,也叫枚举常量 Tue, Wed, Thur, Fri, Sat, Sun, }; 上述代码定义的enum Day是一种枚举类型,{}中内容是枚举类型的可能取值,也可叫作枚举常量. 这些枚举常量都是有值的,默认从0开始,依次往后递增1,如果你愿意赋值也是可以的. 代码如下: #include<stdi

  • C语言详细分析讲解关键字enum与sizeof及typedef的用法

    目录 一.枚举类型的使用方法 二.sizeof 关键字的用法 三.typedef 的意义 四.小结 一.枚举类型的使用方法 enum 是 C 语言中的一种自定义类型 enum 值是可以根据需要自定义的整型值 第一个定义的 enum 值默认为 0 默认情况下的 enum 值是在前一个定义值的基础上加 1 enum 类型的变量只能取定义时的离散值 enum 中定义的值是C语言中真正意义上的常量 在工程中 enum 多用于定义整型常量 下面看一段 enum 的使用代码吧: #include<stdio

  • C语言入门学习笔记之typedef简介

    在单片机和操作系统中 typedef 会经常用到,它可以为某一个类型自定义名称.和#define比较类似.但是又有不同的地方. typedef 创建的符号只能用于数据类型,不能用于值.而#define 创建的符号可以用于值. typedef 是由编译器来解释,而不是预处理器. typedef 使用起来更加灵活. 下面使用typedef定义一个数据类型 int main() { typedef unsigned char BYTE; BYTE c = 10; printf("%d \r\n&quo

  • c语言枚举类型enum的用法及应用实例

    目录 前言 一.枚举的概念 二.枚举的几种用法 1.直接定义枚举值,然后给普通变量赋值. 2.定义带名称的枚举 三.定义枚举别名 四.枚举有什么用,用在哪里? 最后总结: 前言 今天跟大家讲一下我在产品开发时,用枚举(enum)的一些骚操作. 我跟你保证,今天的内容绝对是你在书本和视频学不到的. 为什么要讲枚举呢? 因为我发现它是一个容易被遗忘,同时又非常重要的关键词,大家如果看那些大佬写的程序,真的会发现有非常非常多enum的应用. 让我惊奇的是市面上的一些C语言书籍以及视频课程并没有重视去讲

  • C语言入门篇--注释,关键字typedef及转义字符详解

    目录 注释 1.注释意义 2.两种注释风格 2.1 C语言注释风格 2.2 C++注释风格 关键字typedef 1.注意 2.用法 语法结构 转义字符 1.转义字符及其含义 2.字面 转 特殊 3.特殊 转 字面 注释 1.注释意义 (1)代码中有不需要的代码可以直接删除,也可以注释掉. (2)有些代码比较难懂可以注释一下. 2.两种注释风格 2.1 C语言注释风格 /*xxxxxx*/ 一次可以注释一行或多行,但不能嵌套注释. eg: #include <stdio.h> int main

  • C语言 sizeof 函数详情

    目录 一.sizeof 函数简介 二.sizeof 函数实战 一.sizeof 函数简介 在 C 语言中,char 字符串也是一种非常重要的数据类型,我们除了使用 sizeof 函数获取字符串长度之外,使用 sizeof 函数同样也可以完成字符串长度的获取: 字符串:一般用一对双引号" "括起的一串字符来表示字符串常量,字符串默认以转义字符'\0'结尾,字符串常量是不可被修改的: sizeof 函数会扫描整个字符串,直到碰到第一个字符串结束符 '\0'为止,然后返回计数器值(长度包含'

  • C语言数据类型与sizeof关键字

    目录 一.前言 二.数据类型 1.数据类型有哪些 2.为什么要有数据类型 3.如何看待数据类型 三.sizeof – 计算不同类型变量开辟空间的大小 1.内置类型开辟的空间大小 2.自定义类型开辟的空间大小 3.指针类型开辟的空间大小 4.空类型开辟的空间大小 四.对sizeof 的进一步理解 1.sizeof 为什么不是函数 2.sizeof 的其他使用 一.前言 大家好,欢迎来到C语言深度解析专栏—C语言关键字详解第三篇,在本篇中我们将会介绍C语言当中的数据类型,并由此引出C语言当中的另外一

  • C语言深入探究sizeof与整型数据存储及数据类型取值范围

    目录 1.关键字sizeof 2.整型数据存储深入 3.数据类型取值范围深入 1.关键字sizeof sizeof 与 strlen 是我们日常打代码时经常使用到的两个“工具”.前者是求变量或者类型的大小(单位为字节),后者是求某一字符串的长度.我们很容易产生这样一个误解,即把 sizeof 和 strlen 归为函数一类.事实上 sizeof 并不是一个函数,它是一个操作符.关键字.我们通过一段代码证明它不是函数: #include <stdio.h> int main() { int n

  • Go语言数据类型详细介绍

    目录 一.Go 语言两大数据类型 二.基础类型 三.复合类型 指针 四.数组(array) 五.切片(slice) 六.字典/映射(map) 七.通道(channel) 八.结构体(struct) 九.接口(interface) 十.错误(error) 一.Go 语言两大数据类型 Go 语言数据类型包含基础类型和复合类型两大类. 基础类型包括: 布尔类型 bool. 数值类型 int,int8,int16,int32,int64,float32,float64. uint8,uint16,uin

  • C语言详细分析讲解关键字goto与void的作用

    目录 一.关于goto 二.void 的意义 三.小结 一.关于goto 高手潜规则:禁用 goto 项目经验:程序质量与 goto 的出现次数成反比 最后的判决:将 goto 打入冷宫 下面看一段 goto 副作用分析的代码: #include <stdio.h> #include <malloc.h> void func(int n) { int* p = NULL; if( n < 0 ) { goto STATUS; } p = (int*)malloc(sizeof

  • C语言 数据类型详细介绍

    C 数据类型 在 C 语言中,数据类型指的是用于声明不同类型的变量或函数的一个广泛的系统.变量的类型决定了变量存储占用的空间,以及如何解释存储的位模式. C 中的类型可分为以下几种: 序号 类型与描述 1 基本类型: 它们是算术类型,包括两种类型:整数类型和浮点类型. 2 枚举类型: 它们也是算术类型,被用来定义在程序中只能赋予其一定的离散整数值的变量. 3 void 类型: 类型说明符 void 表明没有可用的值. 4 派生类型: 它们包括:指针类型.数组类型.结构类型.共用体类型和函数类型.

  • 适合初学者的C语言数据类型的讲解

    之前说过写代码是为了解决生活中的问题,比如购物. 假设我们要买一本书,它的价格是10.5,是个小数,也可以是一个整数10,它的书名是钢铁是怎样炼成的,是一组字符串,就像svli@gikvw这些,里面每个称为字符. 我们要去用c语言来去存储这些信息呢,在c语言里面为了能够描述这些类型. 就把小数抽象出来一个数据类型,叫浮点型 把整数抽象出来一个数据类型,叫整型(就是上一个博客里面的int) 把字符抽象出来一个数据类型,就叫字符 10.5 -  小数  -  浮点型 10   -  整数  -  整

  • C语言简明介绍常见关键字的用法

    目录 1.关键字 2.常见关键字 1.关键字 关键字是C语言提供的,不能自己创建关键字: 关键字不能用作变量名,eg:int char:这样的写法是不可取的. 2.常见关键字 auto break case char const continue default do double else enum extern float for goto if int long register return short signed sizeof static struct switch typedef

  • 详解C语言正确使用extern关键字

    利用关键字extern,可以在一个文件中引用另一个文件中定义的变量或者函数,下面就结合具体的实例,分类说明一下. 一.引用同一个文件中的变量 #include<stdio.h> int func(); int main() { func(); //1 printf("%d",num); //2 return 0; } int num = 3; int func() { printf("%d\n",num); } 如果按照这个顺序,变量 num在main函

  • R语言数据类型深入详解

    R语言用来存储数据的对象包括: 向量, 因子, 数组, 矩阵, 数据框, 时间序列(ts)以及列表 意义介绍 1. 向量(一维数据): 只能存放同一类型的数据 语法: c(data1, data2, ...),访问的时候下标从1开始(和Matlab相同);向量里面只能存放相同类型的数据. > x <- c(1,5,8,9,1,2,5) > x [1] 1 5 8 9 1 2 5 > y <- c(1,"zhao") # 这里面有integer和字符串, 整

随机推荐