【C数据(一)】数据类型和变量你真的理解了吗?来看看这篇

  🌈write in front :

🔍个人主页 : @啊森要自信的主页

✏️真正相信奇迹的家伙,本身和奇迹一样了不起啊!

欢迎大家关注🔍点赞👍收藏⭐️留言📝>希望看完我的文章对你有小小的帮助,如有错误,可以指出,让我们一起探讨学习交流,一起加油鸭。 请添加图片描述

文章目录

  • 前言
  • 一、数据类型
    • 1.1字符型
    • 1.2 整型
    • 1.3 浮点型
    • 1.4 布尔类型
  • 二、各种数据类型的⻓度
    • 2.1 sizeof操作符
    • 2.2 数据类型⻓度
    • 2.3 sizeof中表达式不计算
  • 三、signed 和 unsigned
  • 四、数据类型的取值范围
  • 总结


前言

在这里插入图片描述

一、数据类型

C语言主要的数据类型和变量的数据类型有:

  1. 基本数据类型:
  • 整数类型:

    • char:字符类型,占1字节
    • short:短整型,占2字节
    • int:整型,占4字节
    • long:长整型,占4或8字节
    • long long:更长的整型,占8字节
  • 浮点数类型:

    • float:单精度浮点数,占4字节
    • double:双精度浮点数,占8字节
  • 其他类型:

    • void:无类型
    • bool:布尔类型C语言没有内置布尔类型bool,需要包含<stdbool.h>头文件
  1. 变量的数据类型:
  • 自动变量:定义在函数或代码块内的变量,生命周期在函数或代码块结束后结束。
  • 静态变量:使用static声明的变量,生命周期持续整个程序执行期间。
  • 寄存器变量:使用register声明,让变量存储在CPU寄存器中加快访问速度。
  • 外部变量:使用extern声明的变量定义在其他源文件中
  • 指针变量:用于存储地址的值。
  • 数组变量:用于存储多个同类型数据元素。
  • 结构体变量:用于存储不同类型数据元素的集合。
  • 联合体变量:用于存储占用相同内存空间的不同类型数据。
  • 枚举变量:用于定义一组相关常量的值。
#include <stdio.h>
#include <stdbool.h>
int main() 
{
	// 基本数据类型
	char ch = 'a'; // 字符类型
	short num = 10; // 短整型
	int age = 25; // 整型 
	long long bigNum = 1000000000; // 长长整型

	// 浮点数类型
	float price = 19.99; // 单精度浮点 
	double weight = 75.123; // 双精度浮点

	// 其他类型
	void func(); // 无类型
	bool isMale = true; // 布尔类型

	// 变量的数据类型
	static int count = 0; // 静态变量
	register int loop = 0; // 寄存器变量

	int* pNum = &age; // 指针变量
	int arr[10]; // 数组变量

	struct Student 
	{
		char name[20];
		int id;
	} stu; // 结构体变量

	union Data 
	{
		int x;
		char c;
	} data; // 联合体变量

	enum Color { RED, GREEN, BLUE }; // 枚举变量

	printf("char: %c, short: %d, int: %d\n", ch, num, age);
	return 0;
}

1.1字符型

  char
 [signed] char
 unsigned char

1.2 整型

//短整型
 short [int]
 [signed] short [int]
 unsigned short [int]
 
 //整型
 int
 [signed] int
 unsigned int
 
 //⻓整型
long [int]
 [signed] long [int]
 unsigned long [int]
 
 //更⻓的整型
 //C99中引⼊
 long long [int]
 [signed] long long [int]
 unsigned long long [int]

1.3 浮点型

 float
 double
 long double

1.4 布尔类型

C语⾔其实原来并没有为布尔值单独设置⼀个类型,⽽是使⽤整数0
表示假,非零表示真。在C99中也引⼊了布尔类型,是专⻔表⽰真假的。
布尔类型的使⽤得包含头⽂件 <stdbool.h>
布尔类型变量的取值是:true或者false.

 #define bool  _Bool
 #define false 0
 #define true  1

用代码展示

 _Bool flag = true;
 if (flag)
	 printf("i like C\n");

二、各种数据类型的⻓度

2.1 sizeof操作符

C语言中的sizeof操作符用来计算数据类型或表达式所占用的内存字节数。

sizeof主要有以下几种用法:

  1. 计算数据类型大小
sizeof(类型名)

例如:

sizeof(int) // 4 
sizeof(char) // 1
  1. 计算数组元素个数
sizeof(数组名) / sizeof(数组元素类型)

例如:

在这里插入图片描述

  1. 计算结构体大小
sizeof(结构体名)

例如:

在这里插入图片描述

  1. 计算表达式大小
sizeof(表达式)

例如:

在这里插入图片描述

C语言标准只规定sizeof运算符返回一个无符号整数,但并没有明确指定返回值的具体类型

这就可能导致程序的可移植性问题:

  • 不同系统下,sizeof返回值类型可能不同,使用不当类型的格式化输出可能会出错,返回值的类型有可能是unsigned int ,也有可能是 unsigned long ,甚⾄是 unsigned long long ,对应的 printf() 占位符分别是 %u%lu%llu

  • 需要存储sizeof结果的变量也需要使用正确的类型,否则可能会溢出或截断。

C语言提供了size_t类型来解决这个问题:

  • size_t是一个类型别名,它会被定义为当前系统下sizeof返回值的正确类型,可能是unsigned intunsigned long等。

  • 程序使用size_t来存储和操作sizeof结果,就可以保证类型安全且可移植。

  • 格式化输出时使用%zd,它会自动匹配size_t类型

#include <stdio.h>
int main()
{
 int a = 10;
 printf("%zd\n", sizeof(a));
 printf("%zd\n", sizeof a);//a是变量的名字,可以省略掉sizeof后边的()
 printf("%zd\n", sizeof(int));
 printf("%zd\n", sizeof(6 + 8.8));
 return 0;
}

2.2 数据类型⻓度

您总结得很好,我重新梳理一下C语言主要数据类型的长度:

  • char: 1字节
  • short: 2字节
  • int: 32/64位系统通常为4字节
  • long: 4字节
  • long long: 8字节
  • float: 4字节
  • double: 8字节
  • void*: 与系统地址长度相同,32位系统为4字节,64位系统为8字节
  • size_t: 与系统地址长度相同,用来表示sizeof()函数返回值的类型

X86配置下的输出:
在这里插入图片描述

X64配置下的输出:
在这里插入图片描述

2.3 sizeof中表达式不计算

sizeof运算符计算的不是表达式的值,而是类型的大小。

更准确地说,sizeof运算符返回它操作数类型的大小,单位为字节。
如果操作数是一个类型,那么它直接返回该类型的大小;
如果操作数是一个表达式,那么它返回表达式类型的大小。

举个例子:

int main()
{
	int a = 10;
	int b = 20;
	short s = 2;
	int c = 30;

	printf(" %zd\n", sizeof(int)); // 返回int类型大小,如4字节
	printf(" %zd\n", sizeof(a)); // 返回int类型大小,如4字节,和sizeof(int)相同  
	printf(" %zd\n", sizeof(a + b)); // 返回int类型大小,如4字节,计算a + b的类型是int
	printf(" %zd\n", sizeof(s = c + 1));
	printf("s = %d\n", s);

	return 0;
}

在这里插入图片描述

在sizeof(a + b)中:

  • a + b是一个表达式,计算结果是int类型

  • sizeof不计算a + b的实际值,而是直接返回其类型int的大小

  • sizeof(s = c + 1)

    • s = c + 1是一个赋值表达式,计算c+1的值,结果是int类型
    • 但赋值的对象是short类型变量s
    • 所以sizeof返回short类型的大小,即2字节
  • sizeof返回类型大小,不计算表达式值

  • 表达式计算和赋值可能涉及类型转换

sizeof 在代码进⾏编译的时候,就根据表达式的类型确定了,类型的常⽤,⽽表达式的执⾏却要在程序运⾏期间才能执⾏,在编译期间已经将sizeof处理掉了,所以在运⾏期间就不会执⾏表达式了。

三、signed 和 unsigned

signed和unsigned关键字用于指定整数类型的符号:

  • signed: 有符号整数类型,可以表示正数和负数。默认情况下所有整数类型(char、short、int、long)都是signed的。

  • unsigned: 无符号整数类型,只能表示非负整数,范围比signed类型更大。

主要区别:

  1. 存储表示:

    • signed类型用二进制最高位表示数值的符号,正数为0,负数为1

    • unsigned类型最高位都是数值本身,不表示符号。

  2. 数值范围:

    • signed类型的范围依赖于其位宽,如int为-2147483648到2147483647。

    • unsigned类型没有符号位,所以范围比signed类型更大,如uint为0到4294967295。

  3. 运算结果:

    • signed类型在一些运算中可能会发生溢出。

    • unsigned类型不会发生溢出,超出范围直接循环回到最小值。

小例子:

#include <stdio.h>

int main()
{
  unsigned int a = 10;
  signed int b = 10;

  a -= 20;
  b -= 20;

  printf("a = %zu\n", a);
  printf("b = %zd\n", b);

  return 0;
}

在这里插入图片描述

第一种分析:

  • a为unsigned int,范围0-4294967295
  • a原值为10,减20后为-10
  • 但unsigned int没有负数表示,所以-10会溢出计算为最大值4294967295
  • b为signed int,范围-2147483648-2147483647
  • b原值为10,减20后为-10
  • -10正好在signed int范围内,所以结果正确输出为-10
  • 这里unsigned intsigned int在减法溢出后的表现不同:
  • unsigned int溢出后取最大正值
  • signed int保留数值的符号,输出负数

所以这个例子更清晰地展示了signed和unsigned类型在溢出情况下的区别。

二进制重新解释这道题:

题目中有两个变量:

  1. unsigned int a,其范围为0-4294967295

  2. signed int b,其范围为-2147483648-2147483647

开始时:

a = 10
b = 10

然后执行:

a -= 20
b -= 20

分析:

  1. 对于a来说,它是unsigned int类型,没有负数表示。
    当a-=20时,正确的二进制计算是:
a原值: 0000 0000 0000 0000 0000 0000 0000 1010 (10)
a-=20:  0000 0000 0000 0000 0000 0000 0000 0110 (-10,unsigned int没有负数)

由于结果-10超出了unsigned int的范围,所以根据无符号溢出规则,高位溢出位被舍弃,结果保留为最大正值:

0000 0000 0000 0000 0000 0000 0000 0110 溢出为4294967295
  1. 对于b来说,它是signed int类型,可以表示负数
    当b-=20时,二进制计算是:
b原值: 0000 0000 0000 0000 0000 0000 0000 1010 (10)  
b-=20: 1111 1111 1111 1111 1111 1111 1111 1010 (-10)

-10处于signed int的有效范围内,所以结果直接输出-10

总之,通过这个例子可以清晰地看出:

  • unsigned int在溢出时结果取最大正值
  • signed int根据符号位判断正负,直接输出结果

四、数据类型的取值范围

C语言主要的数据类型和其取值范围如下:

用二进制来解释C语言主要数据类型的取值范围:
它的高位为符号位:0表示正数,1表示负数。

  1. char
  • 1字节,表示为8位二进制
  • 高位为符号位,0表示正数,1表示负数
  • 所以取值范围是:0xxx xxxx ~ 0111 1111,即0~ 127为正数,-128 ~ -1为负数
  1. unsigned char
  • 也是1字节8位二进制
  • 但没有符号位,所以全为数据位
  • 取值范围是:0000 0000 ~ 1111 1111,即0~255
  1. short
  • 2字节,表示为16位二进制
  • 高位为符号位,0表示正数,1表示负数
  • 所以取值范围是:0xxx xxxx xxxx xxxx ~ 0111 1111 1111 1111,即0~ 32767为正数,-32768~ -1为负数 (这里的"xxx"代表低15位可以是0或者1,也就是数据位。)
  1. unsigned short
  • 也是2字节16位二进制
  • 没有符号位,所以全为数据位
  • 取值范围是:0000 0000 0000 0000 ~ 1111 1111 1111 1111,即0~65535

总结

以上归纳了C语言主要的数据类型分类,获取数据类型长度的方法,signedunsigned的区别,以及各种数据类型在不同情况下的取值范围范围。感谢你的收看,如果文章有错误,可以指出,我不胜感激,让我们一起学习交流,如果文章可以给你一个帮助,可以给博主点一个小小的赞😘
请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/198764.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python多线程优化:提升程序性能的实例

更多Python学习内容&#xff1a;ipengtao.com 大家好&#xff0c;我是涛哥&#xff0c;今天为大家分享 Python多线程优化&#xff1a;提升程序性能的实例&#xff0c;全文5600字&#xff0c;阅读大约16钟。 多线程是一种有效的并发编程方式&#xff0c;能够提高程序的性能。本文…

交叉编译

1. 交叉开发 交叉编译&#xff1a; 在电脑把程序编写 编译 调试好 再下载到嵌入式产品中运行 编译&#xff1a; gcc 之前编译环境和运行环境是一样的 交叉编译&#xff1a; 编译 把编译代码和运行分开 编译代码在虚拟机中 运行…

WebGL笔记:图形旋转的原理和实现

旋转 1 &#xff09;旋转的概念 三维物体的旋转要比位移复杂一点&#xff0c;三维物体的旋转需要满足以下条件&#xff1a; 旋转轴旋转方向旋转角度 场景举例 模型站在旋转轴的起点进行旋转模型要往左转还是往右转&#xff0c;就是旋转的方向模型旋转的大小就是旋转角度 2 &…

基于SpringBoot的公益慈善平台

✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 一、项目背景介绍&#xff1a; 基于SpringBoot的公益…

使用Python实现SVM来解决二分类问题

下面是一个使用Python实现SVM来解决二分类问题的例子&#xff1a; # 导入所需的库 from sklearn.datasets import make_blobs from sklearn.model_selection import train_test_split from sklearn.svm import SVC import matplotlib.pyplot as plt# 生成一个二分类数据集 X, …

ESP32-Web-Server 实战编程-通过网页控制设备多个 GPIO

ESP32-Web-Server 实战编程-通过网页控制设备多个 GPIO 概述 上节 ESP32-Web-Server 实战编程-通过网页控制设备的 GPIO 讲述了如何通过网页控制一个 GPIO。本节实现在网页上控制多个 GPIO。 示例解析 前端设计 前端代码建立了四个 GPIO&#xff0c;如下死 GPIO 2 在前端的…

STM32F407-14.3.5-01捕获_比较通道

捕获/比较通道 每一个捕获/比较通道都是围绕着一个捕获/比较寄存器(包含影子寄存器) 包括: 捕获的输入部分(数字滤波、多路复用和预分频器)&#xff0c; 输出部分(比较器和输出控制)。 中文参考手册中框图分成了三大模块, 把框图合并成了一个整体,以便更好的理解捕获输…

深度学习之基于百度飞桨PaddleOCR图像字符检测识别系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介主要特点使用步骤 二、功能三、系统四. 总结 一项目简介 # Introduction to PaddleOCR Image Character Detection and Recognition System Based on Baidu…

Java---权限修饰符、final、static

文章目录 1. 权限修饰符2. final(最终态)3. static(静态) 1. 权限修饰符 修饰符同一个类中同一个包中的子类和无关类不同包的子类不同包的无关类private√默认√√protected√√√public√√√√ 2. final(最终态) 1. final关键字是最终的意思&#xff0c;可以修饰成员方法、…

Appium PO模式UI自动化测试框架——设计与实践

1. 目的 相信做过测试的同学都听说过自动化测试&#xff0c;而UI自动化无论何时对测试来说都是比较吸引人的存在。相较于接口自动化来说&#xff0c;它可以最大程度的模拟真实用户的日常操作与特定业务场景的模拟&#xff0c;那么存在即合理&#xff0c;自动化UI测试自然也是广…

《融合SCADA系统数据的天然气管道泄漏多源感知技术研究》误报数据识别模型开发

数据处理不作表述。因为我用的是处理后的数据&#xff0c;数据点这。 文章目录 工作内容1CC040VFD电流VFD转速压缩机转速反馈进出口差压 紧急截断阀开到位进出电动阀开到位发球筒电筒阀开到位收球筒电动阀开到位电动阀2005开到位越站阀开到位 工作内容2工作内容3 工作内容1 任…

金字塔原理 读书笔记

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言第1篇 表达的逻辑第1章 为什么要用金字塔结构归类分组&#xff0c;将思想组织成金字塔自上而下表达&#xff0c;结论先行自下而上思考&#xff0c;总结概括 第2…

Spark---资源、任务调度

一、Spark资源调度源码 1、Spark资源调度源码过程 Spark资源调度源码是在Driver启动之后注册Application完成后开始的。Spark资源调度主要就是Spark集群如何给当前提交的Spark application在Worker资源节点上划分资源。Spark资源调度源码在Master.scala类中的schedule()中进行…

基于SSM的云鑫曦科技办公自动化管理系统设计与实现

基于SSM的云鑫曦科技办公自动化管理系统设计与实现 摘 要: 随着时代的发展&#xff0c;单位办公方式逐渐从传统的线下纸张办公转向了使用个人pc的线上办公&#xff0c;办公效率低下的传统纸质化办公时代的淘汰&#xff0c;转型到信息化办公时代&#xff0c;面对当今数据逐渐膨…

奇数求和(C++)

系列文章目录 进阶的卡莎C++_睡觉觉觉得的博客-CSDN博客数1的个数_睡觉觉觉得的博客-CSDN博客双精度浮点数的输入输出_睡觉觉觉得的博客-CSDN博客足球联赛积分_睡觉觉觉得的博客-CSDN博客大减价(一级)_睡觉觉觉得的博客-CSDN博客小写字母的判断_睡觉觉觉得的博客-CSDN博客纸币(…

Keil5 debug

目录 debug调试功能 基本功能&#xff1a; 程序复位&#xff1a;Reset 运行&#xff1a;Run 停止&#xff1a;Stop 断点调试&#xff08;Breakpoint Debugging&#xff09; 单步调试&#xff1a; 单步调试:Step 单步跳过调试&#xff1a;Step Over&#xff1a; 单步返…

vue项目中使用jsonp跨域请求百度联想接口

一. 内容简介 vue项目中使用jsonp跨域请求百度联想接口 二. 软件环境 2.1 Visual Studio Code 1.75.0 2.2 chrome浏览器 2.3 node v18.14.0 三.主要流程 3.1 代码 核心代码 // 这个是请求函数doLeno() {// 挂载回调函数&#xff0c;不挂载&#xff0c;会报不存在window…

算法中的时间复杂度,空间复杂度

一、前言 算法&#xff08;Algorithm&#xff09;是指用来操作数据、解决程序问题的一组方法。对于同一个问题&#xff0c;使用不同的算法&#xff0c;也许最终得到的结果是一样的&#xff0c;但在过程中消耗的资源和时间却会有很大的区别 衡量不同算法之间的优劣主要是通过时…

【动态规划】求最长递增子序列问题

目录 问题描述递推关系建立递推关系的思路约束条件:以 s [ k ] s[k] s[k] 结尾约束条件:以 s [ k ] s[k] s[k] 开头约束条件:增加子问题参数&#xff08;前缀&#xff09;约束条件:增加子问题参数&#xff08;后缀&#xff09;约束条件:LIS长度为k且末尾元素最小 运行实例 问…

MySQL -DDL 及表类型

DDL 创建数据库 CREATE DATABASE [IF NOT EXISTS] db_name [create_specification [, create_specification] ...] create_specification:[DEFAULT] CHARACTER SET charset_name [DEFAULT] COLLATE collation_name 1.CHARACTER SET&#xff1a…