五大板块(2)—— 指针

参考:五大板块(2)—— 指针
作者:丶PURSUING
发布时间: 2021-03-18 16:01:22
网址:https://blog.csdn.net/weixin_44742824/article/details/114981482

本文为学习笔记,整合课程内容及文章如下:

为什么要使用指针 板块:
参考:原文链接
作者:Cloudkip

目录

  • 一、地址的引入
    • 概念
    • 地址长啥样?
  • 二、指针变量的引入
  • 三、指针分类型与指针偏移量
    • 整型指针,字符指针
    • 函数指针(重点)
      • 无参无返的函数指针
      • 有参有返的函数指针
      • 结构体中的函数指针
      • 规律总结
    • 数组指针(少用)
    • 指针数组(少用)
    • 结构体指针(重点)
      • 定义赋值调用与指针偏移
      • 实际应用例子
    • 野指针
      • 是什么
      • 野指针是怎样生成的?
      • 有什么危害
      • 如何避免
      • malloc与内存泄漏
    • 指针类型小测试
  • 四、指针也可以作为数组传入的形式参数
  • 五、为什么要使用指针?
    • (1)节省内存
    • (2)在子函数中修改被传递过来的对象
    • (3)动态分配内存
    • (4)在指定地址写入数据(目前少用)
    • (5)函数多个返回值

指针,你说他难吧,其实都是在学校学的时候给劝退了,其实很简单,而且学会了之后老是想用,也很好用,以后看到指针就不会有心理障碍啦。

一、地址的引入

概念

地址是一个十六进制表示的整数,用来映射一块空间,是系统用来查找数据位置的依据。地址标识了存储单元空间,而字节就是最小的存储单位。

按字节的编址方式:每一个字节都有一个唯一的地址。例如:一个int型的变量是4个字节,就会对应4个地址,我们只需要取到这个变量的首地址就能得到完整的int型数据。

地址长啥样?

用一个例子感受变量存放的地址:

#include <stdio.h>int main()
{int a=10;int b=11;int* p=&a;int* p2=&b;printf("a的地址是:%p\n",p);printf("b的地址是:%p\n",p2);return 0;
}

结果:可以发现两者地址相差4个字节,说明int型变量用4个字节的空间存放

a的地址是:0x7ea5d1dc
b的地址是:0x7ea5d1d8

大概可以表示为:

在这里插入图片描述

二、指针变量的引入

什么是指针?从根本上看,指针是一个值为内存地址的变量。

正如char型变量存放字符,int型变量存放整型数一样,指针变量存放的是地址,没有什么难理解的。

给指针赋值就是让其指向一个地址。

三、指针分类型与指针偏移量

用sizeof发现linux下所有指针类型的大小均为8字节。

平台:树莓派

首先明白:指针所占用的空间与指针指向的内容和内容的大小无关。
其次明白:在不同的操作系统及编译环境下,指针类型所占用的字节数是不同的
例如:
编译生成16位的代码时,指针占2个字节
编译生成32位的代码时,指针占4个字节
编译生成64位的代码时,指针占8个字节

整型指针,字符指针

#include <stdio.h>int main()
{int a = 5;char b = 'A';int *pa = &a;//存放整型数的指针叫整型指针char *pb = &b;//而这叫字符型指针//printf("int型指针 pa 的地址是%p,指针偏移(++pa)的地址是:%p\n",pa,++pa);//printf("char型指针 pb 的地址是%p,指针偏移(++pb)的地址是:%p\n",pb,++pb);printf("int 型指针pa的地址是%p\n",pa);printf("int 型指针偏移(++pa)后的地址是:%p\n\n",++pa);printf("char 型指针pb的地址是%p\n",pb);printf("char 型指针偏移(++pb)后的地址是:%p\n",++pb);return 0;}

结果:可以看到指针类型不同,其每次偏移的地址量也不同。

pi@raspberrypi:~/Desktop $ ./a.out  
int 型指针pa的地址是0x7ead81ec
int 型指针偏移(++pa)后的地址是:0x7ead81f0char 型指针pb的地址是0x7ead81eb
char 型指针偏移(++pb)后的地址是:0x7ead81ec

不知道你会不会思考,为什么我不使用代码中被注释的两条语句,简短明了,而要使用4条printf。
你尽管试试,打印出来的pa和++pa是一样的,好似是地址没有偏移,这其实关系到了printf的出栈入栈问题,放在六、其他小知识点:printf 里的 a++,++a,真的有鬼!! 中详细展开。

函数指针(重点)

顾名思义,指向函数地址的指针。

无参无返的函数指针

这是函数指针最简单的一种形式

#include <stdio.h>void print()//要被指向的函数
{printf("hello world\n");
}int main()
{void (*pprint)() = NULL;//定义函数指针pprint = print;         //函数指针赋值:指向函数的首地址(就是函数名)//如同数组的首地址,是数组名pprint();        //调用方法1(*pprint)();     //调用方法2printf("函数指针pprint的地址是%p\n",pprint);printf("函数指针偏移(++pprint)后的地址是:%p\n",++pprint);return 0;
}

结果:

hello world
hello world
函数指针pprint的地址是0x1046c
函数指针偏移(++pprint)后的地址是:0x1046d

有参有返的函数指针

稍微上升点难度

#include <stdio.h>int sum(int a,int b)//要被指向的函数
{int c = 0;c = a+b;return c;
}int main()
{int total1;int total2;int (*psum)(int a,int b) = NULL;//定义函数指针psum = sum;           //函数指针赋值,指向函数的首地址(就是函数名)//如同数组的首地址,是数组名total1 = psum(5,6);   //调用方法1total2 = (*psum)(6,9);//调用方法2printf("total1:%d\ntotal2:%d\n",total1,total2);printf("%p\n",psum);printf("%p\n",++psum);return 0;
}

结果:

total1:11
total2:15
0x10440
0x10441

结构体中的函数指针

比较常见的还是和结构体的结合,这个容易看花眼。

#include <stdio.h>
#include <string.h>struct student
{int english;int japanese;int math;int chinese;char name[128];int (*pLanguage)(int english,int japanese);//顺便复习函数指针怎么使用};int Language(int eng,int jap)//函数指针所指向的函数
{int total;total = eng + jap;return total;
}int main()
{int lanSum;struct student stu1 = {.japanese = 90,.english = 100,.math = 90,.name = "华天朱",.pLanguage = Language,};lanSum = stu1.pLanguage(stu1.english,stu1.japanese);printf("stu1的名字是%s,他的语言综合分数是%d\n",stu1.name,lanSum);printf("%p\n",stu1.pLanguage);printf("%p\n",++stu1.pLanguage);return 0;
}

结果:

stu1的名字是华天朱,他的语言综合分数是190
0x10470
0x10471

规律总结

函数指针无非就三步走:

定义
类型 (*指针名)();

void (*pprint)() = NULL;

两个括号很好记

赋值
指针名 = 函数名

pprint = print;

调用
如有参数则调用时传

pprint();        //调用方法1
(*pprint)();     //调用方法2

数组指针(少用)

顾名思义,就是指向数组地址的指针。

目前还没碰到数组指针的使用,涉及即更新

#include <stdio.h>int main()
{int a[3] = {1,2,3};int (*p)[3] = NULL;p = a;printf("%p\n",p);printf("%p\n",++p);return 0;
}

结果:偏移了整个数组的大小12字节

0x7ede61e8
0x7ede61f4

指针数组(少用)

存放一系列指针的数组,本质是数组。

#include <stdio.h>int main()
{int a=1;int b=2;int c=3;int *parray[3] = {&a,&b,&c};int i;printf("指针数组的第一个元素是:%p,地址的内容是:%d\n",parray[0],*parray[0]);return 0;
}

结果:

指针数组的第一个元素是:0x7ed501f4,地址的内容是:1

结构体指针(重点)

定义赋值调用与指针偏移

#include <stdio.h>
#include <stdlib.h>
#include <string.h>struct STU
{int score;char name[128];
};int main()
{struct STU stu1 = {.score = 99,.name = "果粒臣",};//malloc为结构体指针开辟一块空间struct STU *pstu = (struct STU *)malloc(sizeof(struct STU));//结构体指针的赋值1:直接赋值,在此之前要开辟空间pstu->score = 100;strcpy(pstu->name,"华天朱");printf("%s:%d\n",pstu->name,pstu->score);free(pstu);//释放指针,重新指向一段地址//结构体指针的赋值2:指向结构体变量的地址pstu = &stu1;printf("%s:%d\n",pstu->name,pstu->score);//指针偏移printf("%p\n",pstu);printf("%p\n",++pstu);return 0;
}

结果:结构体偏移了4+128个字节

华天朱:100
果粒臣:99
0x7e905170
0x7e9051f4

实际应用例子

用一个结构体指针做一个最简单的学生成绩管理。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>struct stud
{char* name;int score;
};int main()
{int num;int i;printf("需要录入几个学生的成绩?\n");scanf("%d",&num);//这里开辟了num个结构体所需要的空间,动态分配内存struct stud *pstu = (struct stud *)malloc(sizeof(struct stud)*num);for(i=0;i<num;i++){pstu->name = (char* )malloc(sizeof(char)*16);memset(pstu->name,0,sizeof(char)*16);printf("请输入第%d个学生的名字\n",i+1);scanf("%s",pstu->name);printf("请输入第%d个学生的成绩\n",i+1);scanf("%d",&pstu->score);pstu++;}pstu -= num;//指针回头for(i=0;i<num;i++){printf("%s:%d\n",pstu->name,pstu->score);pstu++;}return 0;
}     

结果:

美羊羊:45
废羊羊:100
喜羊羊:60
灰太狼:76

野指针

是什么

野指针指向的地址是随机(又称为:"垃圾"内存)的,无法得知他的地址,操作系统自动对其进行初始化。

野指针是怎样生成的?

(1)创建指针时没有对指针进行初始化
(2)使用free释放指针后没有将其指向NULL

有什么危害

当一个指针成为野指针,指向是随机的,当你使用它时,危害程度也是随机而不可预测的。一般会造成内存泄漏也很容易遭到黑客攻击,只要将病毒程序放入这块内存中,当使用到这个指针时就开始执行。

如何避免

  • 定义指针时进行初始化

如果没有确定指向,就让它指向NULL

NULL在宏定义中是#define NULL (void **) 0,代表的是零地址,零地址不能进行任何读写操作

  • 要给指针指向的空间赋值时,先给指针分配空间,并且初始化空间

简单示例:

//char型指针
char *p = (char *)malloc(sizeof(char));
memset(p,0,sizeof(char));//int型指针
//指针(指向地址)游标卡尺   开辟空间大小
int *p     =     (int *)malloc(sizeof(int));
memset(p,0,sizeof(int));//结构体指针
struct stu *p = (struct stu *)malloc(sizeof(struct stu));
memset(p,0,sizeof(struct stu));

malloc动态内存分配,用于申请一块连续的指定大小的内存块区域以void*类型返回分配的内存区域地址。void *malloc(unsigned int size),因为返回值时void*,所以要进行强制转换。

memset将某一块内存中的内容全部设置为指定的值, 这个函数通常为新申请的内存做初始化工作,是对较大的结构体或数组进行清零操作的一种最快方法。void *memset(void *s, int ch, size_t n);

  • 释放指针同时记得指向NULL
free(p);
p = NULL;

malloc与内存泄漏

情景:
程序刚跑起来的时候没问题,时间久了程序崩溃,大多为内存泄漏。

最常见的情况是在无限的循环中一直申请空间。用malloc申请的空间,程序不会主动释放,只有当程序结束后,系统才回收空间。

避免在循环中一直申请空间,即使合理释放(free,指向NULL)

指针类型小测试

搞几个容易混淆的

int *p[4];
int (*p)[4];
int *p();
int(*p)();
指针数组,数组中存放的是一系列的地址
数组指针,指向一个数组
只是一个普通的函数,其返回值是int* 的指针
函数指针,指向一个函数

四、指针也可以作为数组传入的形式参数

数组作为子函数的形式参数小节中,子函数的形式参数我们用 int array[ ]来定义。

学了指针之后,我们也可以用 int *array来定义.这是因为前者的本质上传入的是数组的首地址,而指针也一样,需要传入数组的首地址。

如下:

#include <stdio.h>int arraySum(int *array,int num)//数组形参,仅仅传递数组的首地址,代表不了个数。
{int sum;int i;for(i=0;i<num;i++){sum+=array[i];}return sum;}int main()
{int sum;int array[5]={0,1,2,3,4};//      sum=arraySum(array,sizeof(array)/sizeof(array[0]));    //传递数组名sum=arraySum(&array[0],sizeof(array)/sizeof(array[0]));//或者传递首元素的地址(&)//sizeof里面只能传入数组名                                                  printf("sum=%d\n",sum);return 0;
}

五、为什么要使用指针?

(1)节省内存

指针的使用使得不同区域的代码可以轻易的共享内存数据,当然也可以通过数据的复制达到相同的效果,但是这样往往效率不太好。

指针节省内存主要体现在参数传递上,比如传递一个结构体指针变量和传递一个结构体变量,结构体占用内存越大,传递指针变量越节省内存,也就是可以减少不必要的数据复制。


在实际做项目的过程中,遇到了结构体多级嵌套导致mcu崩溃的情况(mcu ram吃紧)。

结构体变量和结构体指针变量作为函数参数传递问题

C基础-结构体-4-结构体,结构体指针作为函数传递的参数

#include <stdio.h>
#include <string.h>struct Student {int age;char sex;char name[100];
};void InputStudent(struct Student * pstu) {   //pstu只占四个字节(*pstu).age = 10;strcpy(pstu->name, "张三");pstu->sex = 'F';
}
void OutStudent(struct Student ss) {printf("%d  %c  %s\n", ss.age, ss.sex, ss.name);
}int main(void) {struct Student st;InputStudent(&st);printf("%d  %c  %s\n",st.age,st.sex,st.name);OutStudent(st);return 0;
}

在这里插入图片描述

代码分析;

void OutStudent(struct Student ss) {printf("%d  %c  %s", ss.age, ss.sex, ss.name);
}

此处传递的是一个变量,此变量占的字节空间大,我们可以利用指针,指针只占四个字节空间,而且只存变量st的第一个字节地址,然而指针指向的是整个变量。因为指针前面的类型是struct Student代表的是整个变量。

修改为指针后速度变快,占的内存空间也减小

#include <stdio.h>
#include <string.h>struct Student {int age;char sex;char name[100];
};void InputStudent(struct Student * pstu) {   //pstu只占四个字节(*pstu).age = 10;strcpy(pstu->name, "张三");pstu->sex = 'F';
}
void OutStudent(struct Student * stu) {printf("%d  %c  %s\n", stu->age, stu->sex, stu->name);
}int main(void) {struct Student st;InputStudent(&st);printf("%d  %c  %s\n",st.age,st.sex,st.name);OutStudent(&st);return 0;
}

在这里插入图片描述

当然眼睛是看不出来的,但是理论和事实就是这样的。

(2)在子函数中修改被传递过来的对象

C语言中的 一切函数调用中,值传递都是“按值传递” 的。如果要在函数中修改被传递过来的对象,就必须通过这个对象的指针来完成。

太抽象了不懂?举个栗子:

#include <stdio.h>void add(int a)
{a = a+1;printf("add:a的值为%d\n",a);
}int main()
{int a = 10;add(a);printf("main:a的值为%d\n",a);return 0;
}

结果:可以发现main函数中a的值并没有真正发生改变。

add:a的值为11
main:a的值为10

为什么没有改变呢?
函数add调用时,才申请了一个内存空间(虽然名字一样都是a,但对应不同的存储空间),才有了这个形参变量a,同时把实际参数(main中的a)的值拷贝一份给形式参数(add中的a),函数执行结束后释放空间,这个子函数中的变量自然也被释放了。

其中这个a就是传递入子函数add的对象,如果想要在这个子函数中修改a的值,就要使用指针。

#include <stdio.h>void add(int *a)
{*a = *a+1;printf("add:a的值为%d\n",*a);
}int main()
{int a = 10;add(&a);printf("main:a的值为%d\n",a);return 0;
}

结果:

add:a的值为11
main:a的值为11

传入了main中a的地址,再在子函数中修改这个地址中的内容,当然能够修改成功。

(3)动态分配内存

常常可以看到,程序使用的内存在一开始就进行分配(静态内存分配)。这对于节省计算机内存是有帮助的,因为计算机可以提前为需要的变量分配内存。

但是大多应用场合中,可能一开始程序运行时不清楚到底需要多少内存,这时候可以使用指针,让程序在运行时获得新的内存空间(动态内存分配),并让指针指向这一内存更为方便。

结构体指针实际应用举例中有涉及:

int num;printf("需要录入几个学生的成绩?\n");
scanf("%d",&num);//这里开辟了num个结构体所需要的空间,动态分配内存
struct stud *pstu = (struct stud *)malloc(sizeof(struct stud)*num);

(4)在指定地址写入数据(目前少用)

了解就行,JAVA等其他编程语言实现不了这种操作。

#include <stdio.h>int main()
{volatile int *p = (volatile int *)0x7ead81eb;//强制转化成整型地址*p = 10;                                     //ARM架构 裸机编程 ARM驱动会使用printf("在地址%p中存放的数据是%d\n",p,*p);return 0;
}

结果:

在地址0x7ead81eb中存放的数据是10

注意哈,这个操作运行很有可能

Segmentation fault

这也正常,毕竟可能这地址放有东西或者不允许这样操作。

volatile和编译器的优化有关:

在这里插入图片描述

编译器的优化

在本次线程内,当读取一个变量时,为了提高读取速度,编译器进行优化时有时会先把变量读取到一个寄存器中(寄存器比内存要快!);以后再读取变量值时,就直接从寄存器中读取;当变量值在本线程里改变时,会同时把变量的新值copy到该寄存器中,以保持一致。

当变量因别的线程值发生改变,上面寄存器的值不会相应改变,从而造成应用程序读取的值和实际的变量值不一致。
当寄存器因别的线程改变了值,原变量的值也不会改变,也会造成应用程序读取的值和实际的变量值不一致。

volatile防止优化,每次都要从内存取数据,这样效率会慢于寄存器,但是提高准确度

(5)函数多个返回值

有时候我们总是希望一个功能子函数的返回值可以有很多个,但奈何用return只能返回一个。

碰到实际用上的例子再补充,不硬找例子。

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

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

相关文章

台式计算机机箱都一样吗,别以为组装台式机很简单,机箱选择大有学问

原标题&#xff1a;别以为组装台式机很简单&#xff0c;机箱选择大有学问曾经组装台式机的时候对于机箱完全没有在意&#xff0c;总觉得随便选择一款就可以了&#xff0c; 而且是挑便宜的选择&#xff0c;而那些机箱有便宜也有贵&#xff0c;其实里面的设计完全不一样&#xff…

实现连麦_微信年底放了个大招,视频号重磅升级,打赏直播连麦美颜抽奖齐上...

期待已久的视频号连麦功能来了。这次来的不仅有连麦功能&#xff0c;还有视频号打赏的微信豆体系&#xff0c;创作者想要的入口也有了。让我们一起来看看有什么新功能吧&#xff01;太长不看版本&#xff1a;「附近的人」变「附近的直播和人」连麦上线&#xff0c;还有美颜、抽…

【转】 .NET 打印水晶报表(CrystalReport)时,出现“查询引擎错误 C:/DO...

2019独角兽企业重金招聘Python工程师标准>>> 本地开发环境&#xff1a; Win XP, Visual Studio 2003 Oracle 项目背景&#xff1a; WinForm 工程&#xff0c;在一个表单中用Treeview控件显示 部门层级信息&#xff0c;然后有 按照相同格式&#xff08;layout…

html5 查看图片,html5实现图片预览和查看原图

一、页面元素只有三个简单元素&#xff1a;拖拽区域二、添加简单的样式&#xff1a;.dragarea{width:300px;height:100px;background:#ddd;text-align:center;line-height:100px;}.drag_hover{background:rgba(0,0,0,.4) !important;}.item{width:300px;height:100px;float:lef…

五大板块(4)——链表

参考&#xff1a;五大板块&#xff08;4&#xff09;——链表 作者&#xff1a;丶PURSUING 发布时间&#xff1a; 2021-02-15 09:33:29 网址&#xff1a;https://blog.csdn.net/weixin_44742824/article/details/114981905 目录一、对比链表与数组同样是存放一串数据&#xff0…

boolean类型默认值_「软帝学院」Java的基本数据类型

Java的基本数据类型Java的两大数据类型: 内置数据类型 引用数据类型内置数据类型Java语言提供了八种基本类型。六种数字类型(四个整数型&#xff0c;两个浮点型)&#xff0c;一种字符类型&#xff0c;还有一种布尔型。byte&#xff1a; byte数据类型是8位、有符号的&#xff0c…

五大板块(5)——字符串

参考&#xff1a;五大板块&#xff08;5&#xff09;——字符串 作者&#xff1a;丶PURSUING 发布时间&#xff1a; 2021-03-18 16:03:48 网址&#xff1a;https://blog.csdn.net/weixin_44742824/article/details/114982019 目录一、字符串的定义方式与输出二、字符串的结尾是…

哈尔滨阳光计算机学院是不是黄了,黑龙江这4所野鸡大学,常被误认为是名校,实则害人不浅...

在高考中拿到高分进入心仪的大学&#xff0c;几乎是所有高三党奋斗努力的目标。但并不是所有的考生都能得偿所愿&#xff0c;没有取得高分&#xff0c;想进入好大学&#xff0c;但是又不想复读再经历一次高三的磨砺。如果此时你收到了录取通知书或者电话&#xff0c;告知你被一…

android 打开支付宝扫码页_Chrome 85正式版发布:新增标签页分组功,网页多了也不乱...

IT服务圈儿有温度、有态度的IT自媒体平台文章转载自 OSCHINA 社区[http://www.oschina.net]原文标题&#xff1a;Chrome 85 稳定版发布&#xff0c;页面加载速度提升 10%谷歌今日发布了最新稳定版 Chrome 85。此版本将页面加载速度提高了 10%&#xff0c;并带来了许多标签页方面…

Windows使用技巧

摘自&#xff1a;这些技巧让你windows用起来很爽 —— 小工具&#xff0c;小技巧&#xff0c;删小广告&#xff0c;重装卸载残留 作者&#xff1a;丶PURSUING 发布时间&#xff1a; 2021-03-12 16:09:17 网址&#xff1a;https://blog.csdn.net/weixin_44742824/article/detail…

iOS开发缓存机制之—内存缓存机制

在IOS应用程序开发中&#xff0c;为了减少与服务端的交互次数&#xff0c;加快用户的响应速度&#xff0c;一般都会在iOS设备中加一个缓存的机制。这篇文章将介绍一下如何在iOS设备中进行缓存&#xff0c;本文先介绍一下将内容缓存到内存中&#xff0c;下一篇文章就介绍一下在i…

云计算机教室怎么布线,云和县实验小学计算机教室综合布线及计算机安装预算方案.doc...

云和县实验小学计算机教室综合布线及计算机安装预算方案.doc (2页)本资源提供全文预览&#xff0c;点击全文预览即可全文预览,如果喜欢文档就下载吧&#xff0c;查找使用更方便哦&#xff01;17.90 积分&#xfeff;云和县教育装备和勤工俭学办公室计算机教室改造工程参数设备名…

循环造数据_项目管理数据与信息--DIKW模型

开头的话在PMP中&#xff0c;有一块内容是“项目管理数据与信息&#xff1a;工作绩效数据&#xff08;Work Performance Data&#xff09;&#xff0c;工作绩效信息&#xff08;Work Performance Information&#xff09;&#xff0c;工作绩效报告&#xff08;Work Performance…

基于C语言Ncurse库和链表的简单贪吃蛇小游戏

参考&#xff1a;基于C语言Ncurse库和链表的简单贪吃蛇小游戏 作者&#xff1a;三速何时sub20 发布时间&#xff1a;2020-09-29 10:23:51 网址&#xff1a;https://blog.csdn.net/weixin_44234294/article/details/108829135?spm1001.2014.3001.5501 Ncurses库相关介绍 ncurse…

C 内存分配【转】

c 内存分配 1、程序代码区:存放函数体的二进制代码。 2、全局区数据区&#xff1a;全局数据区划分为三个区域。 全局变量和静态变量的存储是放在一块的。初始化的全局变量和静态变量在一块区域&#xff0c;未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。常量数…

STM32F103五分钟入门系列(一)跑马灯(库函数+寄存器)+加编程模板+GPIO总结

摘自&#xff1a;STM32F103五分钟入门系列&#xff08;一&#xff09;跑马灯&#xff08;库函数寄存器&#xff09;加编程模板GPIO总结 作者&#xff1a;自信且爱笑‘ 发布时间&#xff1a; 2021-04-28 21:17:40 网址&#xff1a;https://blog.csdn.net/Curnane0_0/article/det…

计算机没有程序,计算机小知识:想尝试写程序却没有电脑?这个在线编辑器满足你...

大家好&#xff0c;我是零一&#xff0c;昨天的文章《计算机小知识&#xff1a;手把手教你写出自己的第一个程序&#xff1a;Hello World》发表后&#xff0c;没几分钟就有小伙伴问我&#xff0c;没有电脑&#xff0c;但是真的很想尝试去学习一下编程&#xff0c;应该怎么办&am…

微信小程序时间戳的转换及调用

13位 的时间戳&#xff0c;如下图&#xff1a; 效果图: 1.(utils.js里面的代码): function formatTime(timestamp, format) {const formateArr [Y, M, D, h, m, s];let returnArr [];let date new Date(timestamp); //13位的时间戳, 如果不是13位的, 就要乘1000,就像这样…

基于Wemos D1的感应开盖垃圾桶

参考&#xff1a;基于Wemos D1的感应开盖垃圾桶&#xff08;增加自己的代码实现部分&#xff09; 作者&#xff1a;LEO-max 发布时间&#xff1a;2020-12-29 15:21:26 网址&#xff1a;https://blog.csdn.net/zouchengzhi1021/article/details/111880104?spm1001.2014.3001.55…

电脑计算机主板不启动,电脑主板不能启动的解决方法

电脑主板不能启动的解决方法主板又称主机板、系统板、逻辑板、母板、底板等&#xff0c;是构成复杂电子系统例如电子计算机的中心或者主电路板。下面给大家介绍电脑主板不能启动的解决方法&#xff0c;欢迎阅读!电脑主板不能启动的解决方法电脑主板不能启动的解决方法一&#x…