【C语言】十六进制、二进制、字节、位、指针、数组

news2024/12/24 22:18:17

【C语言】十六进制、二进制、字节、位


文章目录

    • @[TOC](文章目录)
  • 前言
  • 一、十六进制、二进制、字节、位
  • 二、变量、指针、指针变量
  • 三、数组与指针
  • 四、指针自加运算
  • 五、二维数组与指针
  • 六、指向指针的指针
  • 七、指针变量作为函数形参
  • 八、函数指针
  • 九、函数指针数组
  • 十、参考文献
  • 总结

前言

使用工具:
1.控制器:STM32F103C8T6
2.仿真器:STLINK
3.C Primer Plus 第六版-1


提示:以下是本篇文章正文内容,下面案例可供参考

一、十六进制、二进制、字节、位

u16 A_Parameter[10],B_Parameter[10],Flash_Parameter[10];  //

在C语言或类似的环境中,u16 通常被定义为 unsigned short,这意味着它是一个无符号的16位整型数据。由于一个字节包含8位,因此 u16 类型的数据占用2个字节。

对于数组 u16 A_Parameter[10],它包含了10个 u16 类型的元素。每个元素占用2个字节,因此整个数组占用的字节数为:

10 元素×2 字节/元素=20 字节
所以,u16 A_Parameter[10] 占用了20个字节。

A_Parameter[0] 是数组 A_Parameter 的第一个元素,其类型为 u16,即 unsigned short。由于 u16 是一个16位的无符号整型,它占用2个字节。

因此,A_Parameter[0] 占用2个字节。
在这里插入图片描述

#define FLASH_SAVE_ADDR  0X0800E000 	
 

通过仿真器回读芯片FLASH中0X0800E000地址
十六进制表示

31 00 00 00 03 00 04 00 

A_Parameter[0] 占据两个字节,
一个字节占据8位,
十六进制表示0x31 00,
二进制表示0011 0001 0000 0000,
按位表示共有十六个0和1的位组成

在这里插入图片描述

二、变量、指针、指针变量

使用”&”来获取普通变量的地址
&变量名取得变量地址后就可以赋值给指针变量
这个代码里,我们定义了一个变量a, 定义了一个指针变量p。
我们通过运算符&把变量a的内存地址赋值给变量p,所以p指向了变量a的内存存储地址。
通过指针变量来改变变量a的值,因为指针变量p指向的是变量a的地址,所以改变指针变量p指向内存地址的数据就可以改变变量a的值。

unsigned char a ;//
unsigned char *p ;//
void Flash_Write(void)
{
	static unsigned int date=0;//¾²Ì¬Êý¾Ý£¬²»Ë溯Êý½øÈë°ÑÊý¾ÝÇå³ý
	if(++date==65535)date=0;//Êý¾Ý×Ô¼Ó
	B_Parameter[0]=M1.speed;//M1.speed//date	
	B_Parameter[1]=M2.speed;	
	B_Parameter[2]=3;	
	B_Parameter[3]=4;	
	printf("Êý¾ÝÀàÐ͵ĴóС\r\n");	
	printf("char=%d,int=%d,float=%d,double=%d\r\n"
	  ,sizeof((unsigned char)B_Parameter[0])\
		,sizeof((unsigned int)B_Parameter[1])\
		,sizeof((float)B_Parameter[2])\
	  ,sizeof((double)B_Parameter[3]));
  printf("\r\n");	
  a=10;
  p=&a;//È¡µØÖ·
	printf("±äÁ¿aµÄµØÖ·\r\n");	
  printf("&a=0x%x\r\n",&a);	
  printf("p=0x%x\r\n",p);
	printf("&p=0x%x\r\n",&p);	
	printf("\r\n");		
	printf("±äÁ¿aµÄÖµ\r\n");	
  printf("a=%d\r\n",a);
	printf("*p=%d\r\n",*p);	
	printf("\r\n");		
	printf("ͨ¹ýÖ¸Õë±äÁ¿¸Ä±ä±äÁ¿aµÄÖµ\r\n");	
	*p=11;	
	printf("a=%d\r\n",a);	
	printf("*p=%d\r\n",*p);		
	printf("\r\n");		
  printf("ͨ¹ýÄÚ´æµØÖ·¸Ä±ä±äÁ¿aµÄÖµ\r\n");	
	*(unsigned int *)0x200005ac=12;	
	printf("a=%d\r\n",a);	
	printf("*p=%d\r\n",*p);		
	printf("\r\n");			
	STMFLASH_Write(FLASH_SAVE_ADDR,(u16*)B_Parameter,4);	
}

在这里插入图片描述

在这里插入图片描述

三、数组与指针

buff默认的是数组下标为0元素的存储地址,buff和&buff[0]是同一个内存地址,只是写法不一样
unsigned char buff[5]={1,2,3,4,5};
unsigned char 表示占用一个字节,即buff数组中所有成员各占一个字节,如buff0]=0x01,占用一个字节

unsigned char buff[5]={1,2,3,4,5};
unsigned char *p1;
unsigned char *p2;
	p1=buff;
	p2=&buff[0];
	printf("buff=0x%x\r\n",buff);	
  printf("&buff=0x%x\r\n",&buff[0]);	
	printf("p1_addr=0x%x\r\n",p1);	
	printf("p2_addr=0x%x\r\n",p2);	
	printf("\r\n");	
	printf("buff[0]=%d\r\n",buff[0]);	
  printf("*p1=%d\r\n",*p1);	
	printf("*p2=%d\r\n",*p2);	

在这里插入图片描述
在这里插入图片描述

四、指针自加运算

普通变量加减的是数值,而指针变量加减的是地址
首先,代码打印出数组buff每个元素的地址和值。
然后,指针p1被初始化为指向数组的第一个元素(&buff[0])。
接着,通过递增指针p1,代码遍历数组的每个元素,并打印出每个元素的地址和值。

#include <stdio.h>  
  
int main() {  
    unsigned char buff[5] = {1, 2, 3, 4, 5};  
    unsigned char *p1;  
  
    // 打印数组每个元素的地址和值  
    printf("&buff[0]=0x%x buff[0]=%d\r\n", &buff[0], buff[0]);  
    printf("&buff[1]=0x%x buff[1]=%d\r\n", &buff[1], buff[1]);  
    printf("&buff[2]=0x%x buff[2]=%d\r\n", &buff[2], buff[2]);  
    printf("&buff[3]=0x%x buff[3]=%d\r\n", &buff[3], buff[3]);  
    printf("&buff[4]=0x%x buff[4]=%d\r\n", &buff[4], buff[4]);  
  
    p1 = &buff[0]; // 指针p1指向数组的第一个元素  
  
    // 使用指针遍历数组  
    printf("p1=0x%x *p1=%d\r\n", p1, *p1);  
    p1++;  
    printf("p1=0x%x *p1=%d\r\n", p1, *p1);  
    p1++;  
    printf("p1=0x%x *p1=%d\r\n", p1, *p1);  
    p1++;  
    printf("p1=0x%x *p1=%d\r\n", p1, *p1);  
    p1++;  
    printf("p1=0x%x *p1=%d\r\n", p1, *p1);  
  
    printf("\r\n");  
  
    return 0;  
}
	

在这里插入图片描述
在这里插入图片描述

五、二维数组与指针

首先,代码打印出二维数组buff2每个元素的地址和值。
然后,指针p1被初始化为指向数组的第一个元素(&buff2[0][0])。
接着,通过递增指针p1,代码遍历数组的每个元素,并打印出每个元素的地址和值。

#include <stdio.h>  
  
int main() {  
    unsigned char buff2[2][3] = {{1, 2, 3}, {4, 5, 6}};  
    unsigned char *p1;  
  
    printf("五、二维数组与指针\r\n");  
    p1 = &buff2[0][0];  
  
    // 打印数组每个元素的地址和值  
    printf("&buff2[0][0]=0x%x buff2[0][0]=%d\r\n", &buff2[0][0], buff2[0][0]);  
    printf("&buff2[0][1]=0x%x buff2[0][1]=%d\r\n", &buff2[0][1], buff2[0][1]);  
    printf("&buff2[0][2]=0x%x buff2[0][2]=%d\r\n", &buff2[0][2], buff2[0][2]);  
    printf("&buff2[1][0]=0x%x buff2[1][0]=%d\r\n", &buff2[1][0], buff2[1][0]);  
    printf("&buff2[1][1]=0x%x buff2[1][1]=%d\r\n", &buff2[1][1], buff2[1][1]);  
    printf("&buff2[1][2]=0x%x buff2[1][2]=%d\r\n", &buff2[1][2], buff2[1][2]);  
  
    printf("\r\n");  
  
    // 使用指针遍历数组  
    printf("p1=0x%x *p1=%d\r\n", p1, *p1);  
    p1++;  
    printf("p1=0x%x *p1=%d\r\n", p1, *p1);  
    p1++;  
    printf("p1=0x%x *p1=%d\r\n", p1, *p1);  
    p1++;  
    printf("p1=0x%x *p1=%d\r\n", p1, *p1);  
    p1++;  
    printf("p1=0x%x *p1=%d\r\n", p1, *p1);  
    p1++;  
    printf("p1=0x%x *p1=%d\r\n", p1, *p1);  
  
    printf("\r\n");  
  
    return 0;  
}

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

六、指向指针的指针

指针变量分为存储地址和指向地址

a的初始值是*a,是10,存储地址是&a,是0x200005ac
p1的存储地址是&p1,是0x200005bc;指向地址是p1,是0x200005ac,是a的存储地址
p3的存储地址是&p3,是0x200005cc;指向地址是p3,是0x200005bc,是p1的存储地址
*p3是取p3的值,取0x200005bc这个地址的值,而这个地址的值是一个地址,是0x200005ac,是a的存储地址
**p3是取*p3的值,即取0x200005ac这个地址的值,是10

输出结果解释:

&a、&p1、&p3分别打印出变量a、指针p1、指针p3的内存地址。
a=10给变量a赋值。
p1=&a使指针p1指向变量a。
p3=&p1使指针p3指向指针p1。
接下来的几行打印出变量和指针的地址及它们所指向的值,展示了如何通过指针和指向指针的指针来访问和操作变量。

#include <stdio.h>  
  
int main() {  
    unsigned char a;  
    unsigned char *p1;  
    unsigned char **p3;  
  
    printf("六、指向指针的指针变量\r\n");  
    printf("&a=%p\r\n", (void*)&a); // 打印变量a的地址  
    printf("&p1=%p\r\n", (void*)&p1); // 打印指针p1的地址  
    printf("&p3=%p\r\n", (void*)&p3); // 打印指针p3的地址  
    printf("\r\n");  
  
    a = 10;  
    p1 = &a;  
    p3 = &p1;  
  
    printf("&a=0x%x a=%d\r\n", &a, a); // 打印变量a的地址和值  
    printf("&p1=0x%x p1=0x%x\r\n", &p1, p1); // 打印指针p1的地址和值(即变量a的地址)  
    printf("&p3=0x%x p3=0x%x\r\n", &p3, p3); // 打印指针p3的地址和值(即指针p1的地址)  
    printf("*p1=%d\r\n", *p1); // 打印指针p1指向的值(即变量a的值)  
    printf("*p3=0x%x\r\n", *p3); // 打印指针p3指向的值(即指针p1的值,也就是变量a的地址)  
    printf("**p3=%d\r\n", **p3); // 打印指针p3指向的指针所指向的值(即变量a的值)  
  
    return 0;  
}

在这里插入图片描述
在这里插入图片描述

七、指针变量作为函数形参

代码解释:
#include <stdio.h>:包含标准输入输出库,以便使用printf函数。
void TEST7(unsigned char *p4):定义了一个函数TEST7,它接收一个指向unsigned char类型的指针p4作为参数。
在TEST7函数内部,*p4 = 5;语句将指针p4指向的值修改为5。
在main函数中,首先声明了一个unsigned char类型的变量a,并初始化为1。
TEST7(&a);调用TEST7函数,并将变量a的地址作为参数传递。这样,TEST7函数内的修改会影响到main函数中的a变量。
printf(“a=%d\r\n”, a);打印变量a的值,此时a的值已经被TEST7函数修改为5。
这段代码演示了如何通过指针参数在函数间共享和修改数据。

#include <stdio.h>  
  
void TEST7(unsigned char *p4)  
{  
    *p4 = 5;  
}  
  
int main() {  
    unsigned char a;  
    printf("七、指针变量作为函数参数 \r\n");  
    a = 1;  
    TEST7(&a);  
    printf("a=%d\r\n", a);  
    printf("\r\n");  
    return 0;  
}

在这里插入图片描述

八、函数指针

定义函数指针:

unsigned char (*func)(unsigned char,unsigned char);

这行代码定义了一个函数指针func,它指向一个接受两个unsigned char类型参数并返回一个unsigned char类型结果的函数。
定义函数:

unsigned char TEST8(unsigned char v1,unsigned char v2)  
{  
    return (v1+v2);  
}

这行代码定义了一个函数TEST8,它接受两个unsigned char类型的参数v1和v2,并返回它们的和。

使用函数指针调用函数:

func = TEST8;  
a = (*func)(1,2);

首先,将函数TEST8的地址赋给函数指针func。然后,通过函数指针func调用函数TEST8,并传递参数1和2。函数的结果被赋值给变量a。

打印结果:

printf("a=%d\r\n",a);

这行代码打印变量a的值,即函数TEST8的返回值。

#include <stdio.h>  
  
unsigned char (*func)(unsigned char,unsigned char);  
  
unsigned char TEST8(unsigned char v1,unsigned char v2)  
{  
    return (v1+v2);  
}  
  
int main()  
{  
    unsigned char a;  
    printf("函数指针示例\r\n");  
    func = TEST8;  
    a = (*func)(1,2);  
    printf("a=%d\r\n",a);  
    printf("\r\n");  
    return 0;  
}

在这里插入图片描述

九、函数指针数组

定义函数指针数组:

void (*TEST9[3])()={func1,func2,func3};

这行代码定义了一个名为TEST9的函数指针数组,它包含3个元素,每个元素都是一个指向无参数、无返回值(void类型)函数的指针。数组在定义时就被初始化为包含func1、func2和func3这三个函数的地址。

定义函数:

void func1() { printf("func1 \r\n"); }  
void func2() { printf("func2 \r\n"); }  
void func3() { printf("func3 \r\n"); }

这三行代码定义了三个无参数、无返回值的函数func1、func2和func3,它们分别打印出各自的名称。

使用函数指针数组调用函数:

TEST9[0]();  
TEST9[1]();  
TEST9[2]();

这三行代码通过函数指针数组TEST9来调用func1、func2和func3这三个函数。数组的每个元素都是一个函数指针,通过在该指针后面加上()来调用对应的函数。

打印提示信息:

printf("¾Å¡¢º¯ÊýÖ¸ÕëÊý×é \r\n");

这行代码打印出一条提示信息,表明接下来将演示函数指针数组的使用。注意,这里的文本“¾Å¡¢”可能是某种特定编码下的字符,它在正常的ASCII或UTF-8编码下不会显示为预期的文本。在实际编程中,应使用可打印的ASCII或UTF-8字符来编写代码和注释。

#include <stdio.h>  
  
void func1() { printf("func1 \r\n"); }  
void func2() { printf("func2 \r\n"); }  
void func3() { printf("func3 \r\n"); }  
  
void (*TEST9[3])() = {func1, func2, func3};  
  
int main() {  
    printf("函数指针数组示例 \r\n");  
    TEST9[0]();  
    TEST9[1]();  
    TEST9[2]();  
    return 0;  
}

在这里插入图片描述

十、参考文献

位、字节、16进制
c语言指针用法及实际应用详解,通俗易懂超详细!
VSCode中C语言程序输出时,控制台出现中文乱码的问题
VSCode编译C语言代码

总结

本文仅仅简单介绍了【C语言】十六进制、二进制、字节、位验证,评论区欢迎讨论。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JVM面试(六)垃圾收集器

目录 概述STW收集器的并发和并行 Serial收集器ParNew收集器Parallel Scavenge收集器Serial Old收集器Parallel Old收集器CMS收集器Garbage First&#xff08;G1&#xff09;收集器 概述 上一章我们分析了垃圾收集算法&#xff0c;那这一章我们来认识一下这些垃圾收集器是如何运…

某云彩SRM2.0任意文件下载漏洞

文章目录 免责申明搜索语法漏洞描述漏洞复现修复建议 免责申明 本文章仅供学习与交流&#xff0c;请勿用于非法用途&#xff0c;均由使用者本人负责&#xff0c;文章作者不为此承担任何责任 搜索语法 fofa icon_hash"1665918155"漏洞描述 某云采 SRM2.0是一款先…

制作自己的游戏:打砖块

文章目录 &#x1f680; 前言&#x1f680; 前期准备&#x1f680; 玩法设计&#x1f680; 游戏场景&#x1f353; 什么是游戏场景&#x1f353; 绘制左上角积分&#x1f353; 绘制右上角生命值&#x1f353; 绘制砖块&#x1f353; 绘制小球&#x1f353; 绘制挡板&#x1f35…

场景是人工智能第四要素,是垂直领域人工智能的第一要素。

"场景是人工智能的第四要素&#xff0c;与数据、算力、算法同等重要。"拿着技术找场景&#xff0c;还是拿着场景找技术&#xff1f;这个锤子和钉子的问题&#xff0c;一直困扰着各家AI大厂。从近5年的实践来看&#xff0c;拿着场景找技术是更为稳健的&#xff0c;否则…

文章解读与仿真程序复现思路——电力自动化设备EI\CSCD\北大核心《面向电网调峰的聚合温控负荷多目标优化控制方法 》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

R901085689比例流量控制阀配置HE-SP1比例放大器

R901085689比例流量控制阀配置HE-SP1比例放大器的功能是将电信号转换成对应的流量变化&#xff0c;通过调整阀门开度来控制介质的流量。这种转换是通过比例电磁铁实现的&#xff0c;它将输入的电流信号转换成力或位移&#xff0c;从而驱动阀芯移动&#xff0c;实现流量的连续调…

html+css+js网页设计 珠宝首饰模版13个页面

htmlcssjs网页设计 珠宝首饰模版13个页面 网页作品代码简单&#xff0c;可使用任意HTML编辑软件&#xff08;如&#xff1a;Dreamweaver、HBuilder、Vscode 、Sublime 、Webstorm、Text 、Notepad 等任意html编辑软件进行运行及修改编辑等操作&#xff09;。 获取源码 1&…

手机同时传输USB功能与充电的实现及LDR6500的作用

在智能设备日益普及的今天&#xff0c;用户对于手机的功能需求愈发多样化&#xff0c;其中同时实现USB数据传输与充电功能成为了许多用户的迫切需求。这一功能的实现离不开先进的硬件技术和创新的芯片解决方案&#xff0c;而LDR6500正是这样一款能够满足这一需求的USB PD&#…

uni-app 扫码优化:谈谈我是如何提升安卓 App 扫码准确率的

一. 前言 之前的一个项目遭到用户吐槽&#xff1a;“你们这个 App 扫码的正确率太低了&#xff0c;尤其是安卓的设备。经常性的扫码扫不出来&#xff0c;就算是扫出来了&#xff0c;也是错误的结果&#xff01;” 由于之前是扫描二维码的需求&#xff0c;所以没有对扫描条形码…

yolov8-obb旋转目标检测onnxruntime和tensorrt推理

onnxruntime推理 导出onnx模型&#xff1a; from ultralytics import YOLO model YOLO("yolov8n-obb.pt") model.export(format"onnx") onnx模型结构如下&#xff1a; python推理代码&#xff1a; import cv2 import math import numpy as np impo…

全面提升管理效率的智慧园区可视化系统

通过图扑 HT 搭建智慧园区可视化&#xff0c;实时监测和展示园区内各设施的状态与能耗&#xff0c;优化资源配置&#xff0c;提升园区管理效率。

科普神文,一次性讲透AI大模型的核心概念

令牌&#xff0c;向量&#xff0c;嵌入&#xff0c;注意力&#xff0c;这些AI大模型名词是否一直让你感觉熟悉又陌生&#xff0c;如果答案肯定的话&#xff0c;那么朋友&#xff0c;今天这篇科普神文不容错过。我将结合大量示例及可视化的图形手段&#xff0c;为你由浅入深一次…

电脑怎么禁止软件联网?电脑怎么限制软件上网?方法很多,这三种最常用!

在日常使用电脑时&#xff0c;某些软件可能会自动联网&#xff0c;这不仅会消耗网络资源&#xff0c;还可能带来安全风险。此外企业老板考虑到公司员工可能会在工作期间访问无关软件&#xff0c;影响工作效率&#xff0c;因此&#xff0c;很多用户希望能够禁止某些软件联网&…

springboot学生社团管理系统—计算机毕业设计源码26281

目录 摘要 Abstract 1 绪论 1.1 研究背景 1.2 研究意义 1.3论文结构与章节安排 2 学生社团管理系统系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1 数据增加流程 2.2.2 数据修改流程 2.2.3 数据删除流程 2.3 系统功能分析 2.3.1 功能性分析 2.3.2 非功能性分析…

C语言 10 数组

简单来说&#xff0c;数组就是存放数据的一个组&#xff0c;所有的数据都统一存放在这一个组中&#xff0c;一个数组可以同时存放多个数据。 一维数组 比如现在想保存 12 个月的天数&#xff0c;那么只需要创建一个 int 类型的数组就可以了&#xff0c;它可以保存很多个 int …

Linux网络编程IO管理

网络 IO 涉及到两个系统对象&#xff0c;一个是用户空间调用 IO 的进程或者线程&#xff0c;一个是内核空间的内核系统&#xff0c;比如发生 IO 操作 read 时&#xff0c;它会经历两个阶段&#xff1a; 等待内核协议栈的数据准备就绪&#xff1b;将内核中的数据拷贝到用户态的…

vue3 json格式化显示数据(vue3-json-viewer) 对比修改前后数据

需求&#xff1a;对比变更前后数据 npm包下载 npm install vue3-json-viewer --savemain.ts中全局引用 // json可视化 import JsonViewer from "vue3-json-viewer" import "vue3-json-viewer/dist/index.css";app.use(JsonViewer).mount("#app&quo…

鸿蒙界面开发——组件(6):属性字符串(StyledString)文本输入

属性字符串StyledString/MutableStyledString MutableStyledString继承于StyledString&#xff0c;以下统一简称StyledString。 是功能强大的标记对象&#xff0c;可用于字符或段落级别设置文本样式。 通过将StyledString附加到文本组件&#xff0c; 可以通过多种方式更改文本…

深度学习-用神经网络NN实现足球大小球数据分析软件

文章目录 前言一、 数据收集1.1特征数据收集代码实例 二、数据预处理清洗数据特征工程&#xff1a; 三、特征提取四、模型构建五、模型训练与评估总结 前言 预测足球比赛走地大小球&#xff08;即比赛过程中进球总数是否超过某个预设值&#xff09;的深度学习模型是一个复杂但有…

霍尼韦尔、书客、米家护眼大路灯怎么样?终极测评对比和护眼灯王者机型

霍尼韦尔、书客、米家护眼大路灯怎么样&#xff1f;护眼大路灯的重要性不容忽视&#xff0c;它是我们日常生活中用眼的必备工具&#xff0c;也是眼睛能够得到保护重要一环。近年来&#xff0c;护眼大路灯市场呈现出国际大牌的垄断局面&#xff0c;但这也带来了一些问题。为了争…