【C语言】基本数据类型详解

简介: 本文讲解:C语言中数据类型常量与变量的详解。

1、什么是数据类型?

数据类型在我们日常生活中就是表示每一类数据的标识,我们通过大脑来存储这些数据标识,那么在计算机中我们认为数据类型就是计算机表示数据的一个属性,我们程序员通过编译器和解释器向计算机表示我要进行的数据类型操作。当然这些数据存储在计算机当中。下面我就来讲解C语言中数据的不同类型以及它们所占的存储空间、怎样定义一个常量、常量的命名规范......


1.1数据类型的分类

🤼那么在C语言中数据类型分为四种:

  • 基本数据类型-整数型、浮点型和字符型
  • 空类型-void类型
  • 构造类型-数组、结构体、共用体、枚举类型
  • 指针类型- *

image.png

本期我们主要讲解最常用的-基本数据类型,后面几期我们再来探讨其他几种数据类型


1.2基本数据类型有哪些?

C语言中基本数据类型有整数类型浮点类型,他们都是算术类型。分别为:

char(%c)- 字符型:可以是大小写字母(例'a'、'A'),数字(例'1'),转义字符(例'\t')等,它在16位编译器、32位编译器、64位编译器中都占1个字节

short(%d)- 短整型:可以是小型数字取值较短,它在16位编译器、32位编译器、64位编译器中都占2个字节

int(%d)- 整形:可以是中长度的一个数字取值比,正常我们定义一个整形变量就用int,它在16位编译器占2个字节、32位编译器占4个字节、64位编译器占4个字节

long(%ld)- 长整型:当我们要求的数字较大超出了正常范围,我们可以用long来定义,它在16位编译器、32位编译器都占4个字节、64位编译器中占8个字节

long long(%lld)- 更长的长整型:当数字太大了,已经数不过来了,我们可以用long long,它在16位编译器、32位编译器、64位编译器中都占8个字节

float(%f)- 单精度浮点型:我们一般都用float来表示小数,如6.6,6.66这种小数位数少的,它在16位编译器、32位编译器、64位编译器中都占4个字节

double(%lf)- 双精度浮点型:小数位数过大,如6.666699897我们就用双精度来表示,它在16位编译器、32位编译器、64位编译器中都占8个字节

long double(%llf)- 更高精度的浮点型long double是C99中新增的数据类型。ANSIC标准规定了double类型为64 位(8 个字节)浮点数, 但未规定long double类型的位数,只规定了long double的精度不少于double的精度。它的不同的系统位占的字节也不同。

数据类型 系统16位 系统32位 系统64位
char 1(字节) 1(字节) 1(字节)
short 2(字节) 2(字节) 2(字节)
int 2(字节) 4(字节) 4(字节)
long 4(字节) 4(字节) 4(字节)
long long 8(字节) 8(字节) 8(字节)
float 4(字节) 4(字节) 4(字节)
double 8(字节) 8(字节) 8(字节)

以上是我们对基本数据类型的一个初步了解,以下内容我们来深入了解一下什么是基本数据类型


那么我们想要得到某个类型的存储大小,我们可以使用sizeof运算符,表达式sizeof(数据类型)来得到该类型或对象在存储占用多少字节数,🤼‍♀️下图所示:

image.png

注意,各个类型的存储大小与系统位相关,上图是以目前主流的64位操作系统,诸位可以打开编译器试试(●'◡'●)


1.3整型

整形家族:char - 字符数据类型、short  - 短整型、int  - 整形、long - 长整型、long long  - 更长的整形

类型 存储大小 取值范围 格式符
char 1字节 -128 到 127 或 0 到 255 %c
int 4 字节  -2,147,483,648 到 2,147,483,647 %d
short 2 字节 -32,768 到 32,767 %d
long 8 字节 -2,147,483,648 到 2,147,483,647 %ld
long long 8 字节 -2^64到2^64-1 %lld

怎样理解C语言中的整型呢,见名知意,是指一个没有小数位数的整数。只不过在计算机中我们称为整型。在生活中一个整数,可以是负数、正数,计算机里面也是一样的可以是正数、负数。那么计算机表示数可以是八进制、十进制、十六进制等。表示八进制数,数字前面加0(零)。表示十进制数不需要加任何符号,C语言中默认一个数字为十进制。表示十六进制数,则在数字前面加0x(零x)。


有一程序,定义一个数,分别输出它的八进制数、十进制数、十六进制数:

#include<stdio.h>intmain()
{
intn=20;
printf("对应的八进制数为:  %#o\n", n);//%o输出八进制形式printf("对应的十进制数为:  %d\n", n);//%d输出十进制形式printf("对应的十六进制数为:%#x\n", n);//%x输出十六进制形式return0;
}

输出的结果为:

对应的八进制数为:    024
对应的十进制数为:    20
对应的十六进制数为:0x14


printf 可以使用使用格式控制串“%o”、“%X”分别输出八进制整数和十六进制整数,并使用修饰符“#”控制前导显示


1.4浮点型

浮点型家族:float - 单精度浮点型字符、double - 双精度浮点型字符

类型 存储大小 值范围 精度 格式符
float(单精度) 4 字节 1.2E-38 到 3.4E+38 6 位有效位 %f
double(双精度) 8 字节 2.3E-308 到 1.7E+308 15 位有效位 %lf
long double 16 字节 3.4E-4932 到 1.1E+4932 19 位有效位 %llf

怎么理解浮点型呢,一个小数66.6它可以写为6.66*10^1也可以写为0.666*10^2。这个数它的小数点是可以移动的漂浮不定的,我们称之为浮点型。在C语言中浮点型分为单精度浮点型双精度浮点型。我们如何定义它呢?

如一个小数6.6。在C语言中我们默认这个小数为double类型(双精度浮点型字符),但是这个小数6.6貌似不是很大好像不用那么高的精度来给它定义。那么我们可以在6.6后面加上一个f6.6f这就形式我们一目了然这是一个单精度浮点型6.6


如何得到单精度与双精度所占字节以及取值范围呢?步骤如下图所示:

#include <stdio.h>#include <float.h>//引入头文件<float.h>intmain()
{
printf("float 存储最大字节数 : %lu \n", sizeof(float));//sizeof取float的字节数printf("float 最小值: %E\n", FLT_MIN);//输出float最小值printf("float 最大值: %E\n", FLT_MAX);//输出float最大值printf("精度值: %d\n", FLT_DIG);//输出float精度值printf("double 存储最大字节数 : %lu \n", sizeof(double));//sizeof取double的字节数printf("double 最小值: %E\n",DBL_MIN);//输出double最小值printf("double 最大值: %E\n", DBL_MAX);//输出double最大值printf("精度值: %d\n", DBL_DIG);//输出double精度值return0;
}

image.gif

  • float.h是C语言标准库头文件,提供了浮点型的范围和精度的宏,一般用于数值分析。 float.h包含了一组与浮点值相关的依赖于平台的常量。DBL_MAX:double型的最大值DBL_MIN:double型的最小值FLT_MAX:float型的最大值FLT_MIN:float型的最小值。分别把这几个参数带入输出式中,可以得到结果。
  • 那么float.h被定义宏有float、double、long double。上图中我只列出了两个最常用的类型。
  • %E 为以指数形式输出单、双精度实数。


以下为输出结果,可以上面代码深入了解一下:

image.png

总结:

  • 引入头文件#include<float.h>
  • DBL_MAX:double型的最大值
  • DBL_MIN:double型的最小值
  • FLT_MAX:float型的最大值
  • FLT_MIN:float型的最小值
  • 字符型,单独的一个字符用英文状态下单引号''引起来如'A'、'*'、'a'、'\t';
  • 字符型,字符串应用英文状态下的""引起来如"ABC";
  • 浮点型,单精度6.6应写为6.6f,双精度6.6还是6.6(C语言默一个小数为双精度浮点型)。

2、变量与常量

基本数据类型分为常量变量


2.1变量与常量是什么

在日常生活中,一个人的姓名、身份证号码、性别、血型。我们理解为这个人的不变的量,这里也就是常量。那么这个人的年龄、体重、相貌、工资。我们理解为这个的可变的量,这里也就是变量。那么理解上述两段话后,我们就不难理解C语言中常量与变量是怎么个回事了。

C语言中可以改变的值我们称为变量,不可改变的值我们称为常量


2.2怎样定义一个常量

通过赋值来定义,看一个小例子定义一个int a=10和一个char ch='A',意思是定义一个整形变量a,把10赋值给a和定义一个字符型变量ch,把A赋值给ch。我们可以这样理解=号前面是变量的命名,=号后面是一个量这个量可以变。我们可以再通过赋值来改变,亦或者通过scanf输入来改变。

#include<stdio.h>intmain() {
inta=10;//定义一个整形变量a=10charch='A';//定义一个字符型变量ch=Aprintf("a=%d,ch=%c\n\n", a,ch);//输出变量a,cha=20;//把整形变量a改为20ch='B';//把字符型变量ch改为Bprintf("a=%d,ch=%c\n", a,ch);//输出变量a,chreturn0;
}

image.gifimage.png

众所周知,C语言是一个从按照顺序来执行代码的一个语言,上述代码中,首先我定义了一个整形变量a=10和一个字符型变量ch=‘A’,分别输出10和A,后来我又通过赋值操作把变量a该为20,变量ch改为B,我再输出20与B。 通过这一个小案例,我们可以知道如何定义一个变量。

定义一堆常量,直接上代码:

#include<stdio.h>intmain()
{
charzifu='A';//定义一个字符变量zifu,赋值给它Achar*zifu2="ABC";//定义一个指针字符变量指向名为zifu2字符串的首地址,赋值给它ABCshortduan=1010;//定义一个短整型变量duan,赋值给它1010intzheng=2022;//定义一个整形变量zheng,赋值给它2022longchang=10000;//定义一个长整型变量chang,赋值给它10000longlongchaoChang=100000000;//定义一个更长的长整型chaoChang,赋值给它100000000printf("定义一个字符         %c\n",zifu);
printf("定义一个字符串       %s\n", zifu2);
printf("定义一个短整型       %d\n", duan);
printf("定义一个整形         %d\n", zheng);
printf("定义一个长整型       %ld\n", chang);
printf("定义一个更长的长整型 %lld\n", chaoChang);
return0;
}

image.gif输出结果:

image.png


2.3变量的命名规范

  • 只能由字母、数字和下划线( _ )组成。
  • 不能以数字开头。
  • 长度不能超过63个字符。
  • 变量名中区分大小写的。
  • 变量名不能使用关键字。

3、变量的分类

变量分为局部变量全局变量局部变量与全局变量之前,我们必须了解到作用域和生命周期这两个概念。

作用域作用域(scope)是程序设计概念,通常来说,一段程序代码中所用到的名字并不总是有效/可用的而限定这个名字的可用性的代码范围就是这个名字的作用域。

  • 局部变量的作用域是变量所在的局部范围。
  • 全局变量的作用域是整个工程。

生命周期,变量的生命周期指的是变量的创建到变量的销毁之间的一个时间段。

  • 局部变量的生命周期是:进入作用域生命周期开始,出作用域生命周期结束。
  • 全局变量的生命周期是:整个程序的生命周期。

3.1局部变量

局部变量我们理解为括号{}内定义的变量,局部变量的作用域是变量所在的局部范围局部变量的生命周期是:进入作用域生命周期开始,出作用域生命周期结束。我们看代码:

#include<stdio.h>intmain() 
{
inta=20; //定义一个局部变量a=20printf("a=%d\b", a);
return0;
}


结果: a=20

这就是一个简单的局部变量,当然我们可以再通过赋值、scanf输入来改变这个变量。


#include<stdio.h>intmain()
{
    {
inta=20;
printf("a=%d\n", a);
    }
return0;
}

image.gif

输出结果:a=20

那么我们把printf语句放在第二个{}外面,上个程序与下个程序有什么不同呢?

#include<stdio.h>
int main()
{
  {
    int a = 20;
  }
  printf("a=%d\n", a);
    return 0;
}

image.gif

会显示未定义标识符a

image.png

为什么这个地方会显示a未定义标识符呢? 因为我们是在第二个{}里面定义的a=20,脱离了第二个{}后我们就脱离了这个{}的作用域,也就是上方这句话的意思局部变量的生命周期是:进入作用域生命周期开始,出作用域生命周期结束。


3.2全局变量

全局变量我们理解为括号{}外定义的变量,全局变量的作用域是整个工程。局变量的生命周期是:整个程序的生命周期。

#include<stdio.h>inta=10;//定义一个全局变量a=10intmain() 
{
printf("a=%d\b", a);
return0;
}

image.gif

结果:a = 10

那么这就是一个简单的定义全局变量程序,我们刚开始学习就应该以理解为主,在后来的学习中,我们的难度才会慢慢增长。不要站架没学会就想着怎么出拳,一步一步来。


🤼下面我们来看一个程序:

#include<stdio.h>inta=2021;//定义一个全局变量a=2021intmain() 
{
intb=2022;//定义一个局部变量a=2023;//把a更改为2023printf("a=%d\n", a);//输出a现在的值return0;
}

image.gif

结果:a=2023

可能有些小伙伴看了这个,就有些疑惑了,诶你不是定义a=2021了吗,为啥输出结果为2023呢?诸位注意,我定义的a=2021是在{}前面定义的,我们成这个为全局变量,而{}内定义的a=2023是一个全局变量。所以我们认为局部变量与全局变量名冲突时,我们优先输出局部变量。这就是为什么上述结果为2023。

总结🥊:

    • 局部变量的作用域是变量所在的局部范围。
    • 全局变量的作用域是整个工程。
    • 局部变量的生命周期是:进入作用域生命周期开始,出作用域生命周期结束。
    • 全局变量的生命周期是:整个程序的生命周期。

    4、常量的使用

    4.1常量分类

    C语言中常量与变量的命名是有着极大的不同的,上面我们说过常量是不可改变的量,那么设置它的时候自然有着不同之处。C语言中的常量有以下几种:

      • 常见常量
      • const修饰的常变量
      • #define定义的标识符常量
      • 枚举常量

      4.2#define宏定义

      #define是什么?

      #define命令是C语言中的一个宏定义命令,它用来讲一个标识符定义为一个字符串,该标识符被称为宏名,被定义的字符串称为替换文本。该命令有两种格式:一种是简单的宏定义(不带参数的宏定义),另一种是带参数的宏定义。

      #define是一个宏定义,它定义一个文本给这个文本赋不变的值,我们可以在main函数里面通过这个文本调用这个文本所赋给的值。这个值是不变的,所以我们称为常量。


      🤼以下有一程序输入圆的半径求圆的面积:

      include<stdio.h>#define pai 3.14//宏定义文本pai=3.14intmain()
      {
      doubler=0;
      doubles=0;
      printf("请输入圆的半径:");
      scanf("%lf", &r);
      s=pai*r*r;
      printf("圆的面积为:%.1lf\n", s);
      return0;
      }

      image.gif

      🤼‍♀️结果为:

      image.png

      那么这个程序就用到了宏定义#define,我令pai为宏名(标识名),赋值给它3.14。


      大家思考一下上述宏定义,只是定义一个值。如果定义一个算术类型呢?例如#define N 3+2,那么这个定义是否可以呢?例:有一矩形已知一边长宏定义为10,另一边长为5,并求出它的面积,我们来看代码:

      #include<stdio.h>#define N 4+6 //4+6没有括号intmain()
      {
      intn=5;
      ints=0;
      s=N*n;
      printf("矩形的面积为:%d\n",s);
      return0;
      }

      image.gif

      输出的结果为:

      矩形的面积为:34


      为什么会这样呢,在编译时我们预想s=10*5,实际打印结果是34原因是在预处理阶段,编译器将 s=10*5 处理成 s=4+6*5,这就是 define 宏的边缘效应,所以我们应该写成 #define N (2+3)

      image.png

      这样我们才能输出正确的答案 :

      矩形的面积为:50


      🤼‍♀️当然你也可以#define多个命名,直接看代码

      #include<stdio.h>#define A 10#define B 20#define C '\n'intmain() 
      {
      intS=0;
      S=A*B;
      printf("A*B=%d", S);
      printf("%c", C);
      return0;
      }

      image.gif

      image.png

      上述程序我们可以看到宏定义可以定义转义字符'\n'换行

      总结🥊:

        • 宏定义一个算术类型时要加()如:#define N (2+3)
        • 宏定义可以是转义字符,如:'\n'、'\t'

        4.3const修饰的常变量

        const是一个关键字,那么const修饰的为什么可以是一个常量,也可以是一个变量呢?下面我就来讲解。首先,我们要知道定义一个const修饰的常量的格式:const int a =20 ;1、const-关键字2、int-数据类型3、a-变量名4、20-变量值5、;-结束符

        🤼当const修饰一个常量时,这个常量的值是不可更改的:

        image.gifimage.png

        我们可以看到上图中,const 修饰整形变量a=20后,a再不能被赋值了。也就是说const把a定死了,它只能是20。


        🤼‍♀️当const修饰一个指针变量时,这个指针变量可以通过指向不同的地址来改变:

        #include<stdio.h>intmain() 
        {
        inta=20;
        constint*p=&a;
        printf("%d\n", *p);
        a=30;
        printf("%d\n", *p);
        return0;
        }

        image.gif

        结果为:20

                     30


        当把 const 放最前面的时候,它修饰的就是 *p,那么 *p 就不可变。*p 表示的是指针变量 p 所指向的内存单元里面的内容,此时这个内容不可变。其他的都可变,如 p 中存放的是指向的内存单元的地址,这个地址可变,即 p 的指向可变。但指向谁,谁的内容就不可变。

        #include<stdio.h>intmain() 
        {
        inta=20;
        int*constp=&a;
        printf("%d\n", *p);
        a=30;
        printf("%d\n", *p);
        return0;
        }

        image.gif

        结果:20

                  30


        总结🥊:

          • const修饰一个常量时,这个常量是不可改变的
          • const修饰一个指针变量时,这个指针变量可以通过地址来改变原本的值

          4.4枚举常量

          上面我们已经见过const字符常量、还有宏常量了但是如果想要定义一组有意义的数字,这一组的数字都有“排比”一样的规律我们可以定义为枚举常量。

          🤼直接看代码:

          #include<stdio.h>intmain() 
          {
          enumStudent {
          shuxue,
          yingyu,
          wuli    };
          printf("shuxue=%d\n", shuxue);
          printf("yingyu=%d\n", yingyu);
          printf("wuli=  %d\n", wuli);
          return0;
          }

          image.gif

          image.png

          那么括号中的shuxue,yingyu,wuli都枚举常量。那么枚举常量只能是int类型的,且声明和赋值整数,平常在排列时用的较多。至于他的用法以后我会在后面几期文章内提到,我们暂时只用知道什么是枚举常量。

          注意,枚举常量的默认是从0开始,依次向下递增1的


          image.gif好了,本期博文到这里就结束了。下期预告:选择结构。

          相关文章
          |
          1月前
          |
          存储 程序员 编译器
          C 语言中的数据类型转换:连接不同数据世界的桥梁
          C语言中的数据类型转换是程序设计中不可或缺的一部分,它如同连接不同数据世界的桥梁,使得不同类型的变量之间能够互相传递和转换,确保了程序的灵活性与兼容性。通过强制类型转换或自动类型转换,C语言允许开发者在保证数据完整性的前提下,实现复杂的数据处理逻辑。
          |
          16天前
          |
          C语言
          【C语言程序设计——入门】基本数据类型与表达式(头歌实践教学平台习题)【合集】
          这份文档详细介绍了编程任务的多个关卡,涵盖C语言的基础知识和应用。主要内容包括: 1. **目录**:列出所有关卡,如`print函数操作`、`转义字符使用`、`数的向上取整`等。 2. **各关卡的任务描述**:明确每关的具体编程任务,例如使用`printf`函数输出特定字符串、实现向上取整功能等。 3. **相关知识**:提供完成任务所需的背景知识,如格式化输出、算术运算符、关系运算符等。 4. **编程要求**:给出具体的代码编写提示。 5. **测试说明**:包含预期输入输出,帮助验证程序正确性。 6. 文档通过逐步引导学习者掌握C语言的基本语法和常用函数,适合初学者练习编程技能。
          32 1
          |
          5月前
          |
          存储 安全 C语言
          C语言中的数据类型
          C语言中的数据类型
          110 1
          |
          5月前
          |
          存储 C语言
          C语言数据类型、变量和运算符以及printf相关问题
          C语言数据类型、变量和运算符以及printf相关问题
          |
          1月前
          |
          存储 编译器 C语言
          【C语言】数据类型全解析:编程效率提升的秘诀
          在C语言中,合理选择和使用数据类型是编程的关键。通过深入理解基本数据类型和派生数据类型,掌握类型限定符和扩展技巧,可以编写出高效、稳定、可维护的代码。无论是在普通应用还是嵌入式系统中,数据类型的合理使用都能显著提升程序的性能和可靠性。
          66 8
          |
          3月前
          |
          存储 C语言
          【c语言】数据类型和变量
          本文介绍了C语言中的数据类型和变量。数据类型分为内置类型和自定义类型,内置类型包括字符型、整型、浮点型等,每种类型有不同的内存大小和取值范围。变量分为全局变量和局部变量,它们在内存中的存储位置也有所不同,分别位于静态区和栈区。通过示例代码和图解,详细阐述了这些概念及其应用。
          67 1
          |
          3月前
          |
          C语言
          3.4 C语言基本数据类型2
          在C语言中,声明一个整型(int)变量时,需先写入&#39;int&#39;关键字,后跟变量名并以分号结尾。若同时声明多个变量,可在&#39;int&#39;后用逗号分隔列出所有变量名。例如,`int erns;` 或 `int hogs, cows, goats;` 都是合法声明。变量声明后需通过赋值语句如 `cows = 112;` 或使用函数如 `scanf()` 来初始化其值。
          77 10
          |
          3月前
          |
          存储 程序员 C语言
          3.1 C语言基本数据类型
          在C语言中,整数类型如`int`类型是很有用的,它属于有符号整型,意味着该类型的值必须是整数,并且可以是正整数、负整数或者零。`int`类型的数值范围依据计算机系统有所不同,通常取决于系统的位宽。例如,在早期16位的IBM PC兼容机上,`int`类型使用16位存储,取值范围为-32768至32767;而在当前32位系统中,使用32位存储,拥有更宽泛的取值范围。随着64位处理器的普及,`int`类型能够存储的整数范围将进一步扩大。根据ISO C标准,`int`类型的最小取值范围被规定为-32768到32767。系统通常会利用一个特殊的位来表示整数的正负。
          86 10
          |
          3月前
          |
          C语言
          3.1C语言基本数据类型
          在C语言中,初始化变量是指为变量设定初始值,通常在声明时直接完成,例如 `int cows=32;`。应注意避免在同一语句中混合初始化与未初始化的变量,如 `int dogs, cats=94;` 这样的写法容易引起误解。此外,整型常量如21、32等在C语言中被视为int类型,但非常大的整数则不然,且带有小数点或指数的数值不属于整型常量。
          41 9
          |
          4月前
          |
          存储 C语言 索引
          C 语言数据类型详解
          C语言中的数据类型主要包括基本数据类型、构造数据类型和用户定义数据类型。基本类型如整型(`int`)、字符型(`char`)、浮点型(`float`)、双精度浮点型(`double`)和无符号整型(`unsigned int`)。构造类型包括数组(`Array`)、结构体(`Struct`)、共用体(`Union`)和枚举(`Enum`)。用户定义类型则通过`typedef`为已有类型定义新名称,并可通过结构体和共用体自定义复合数据结构。此外,还有指针类型用于存储变量地址,以及`signed`、`unsigned`、`short`、`long`等类型修饰符。
          125 11

          热门文章

          最新文章