指针浅析

C++中强指针和弱指针使用原则浅析 使用C++开发大型项目时,指针的管理是ra 阅读详情

目录

0 指针

0.1 分类

0.2 解析方法

0.3 数据类型

0.4 普通指针

参数传递

1 多级指针

(1) char **p

参数传递

(2) char ***p

2 指针数组

(1) char *p[]

参数传递

(2) char *p[][3]

参数传递

(3) char **p[][3]

参数传递

3 数组指针

(1) char (*p)[4]

参数传递

(2) char (*p)[3][4]

参数传递

(3) char * (*p)[3]

参数传递

(4) char (**p)[4]

参数传递

4 数组指针数组

(1) char (*p[])[4]

参数传递

(2) char (*p[])[3][4]

参数传递

(3) char * (*p[])[3][4]

(4) char * (*p[][2])[3][4]

参数传递

5 指针数组指针

6 函数指针

参数传递

7 指针函数

参考


0 指针

0.1 分类

如上图

0.2 解析方法

0.3 数据类型

一维数组的数据类型为 char *,多维数组因为必须限制除第一维外所有的维度,故数据类型如下举例:

char array1[] = "a01";
char *p1 = array1;

char array2[][4] = {"a01", "a02", "a03"};
char (*p2)[4] = array2;

char array3[][3][4] = {							
						{"a01","a02","a03","a04"},
						{"b01","b02","b03","b04"},
					  };   
char (*p3)[3][4] = array3;

array1 的维度为:(4,)    array1 和 p1 的数据类型为:char *

array2 的维度为:(3, 4)    array2 和 p2 的数据类型为:char (*)[4]

array3 的维度为:(2, 3, 4)    array3 和 p3 的数据类型为:char (**)[3][4]

而对于如下

char **p4 = &p1;
char (**p5)[4] = &p2;
char (**p6)[3][4] = &p3;

p4 的数据类型为:char **

p5 的数据类型为:char (**)[4]

p6 的数据类型为:char (**)[3][4]

char **p7 = &p5;
char (**p8)[4] = &p6;
char (**p9)[3][4] = &p7;

p7 的数据类型为:char ***

p8 的数据类型为:char (***)[4]

p9 的数据类型为:char (***)[3][4]

0.4 普通指针

对于最普通的指针,如下图所示

举例

char v = 'a';
char *p = &v;

char *p = “a01”;

参数传递

p 是指针,其数据类型为 char *,需要 char ** 来接收

char *p;
char **rec = &p;

1 多级指针

(1) char **p

char c = 'a';
char *p1 = &c;
char **p = &p1;

参数传递

p 是指针,其数据类型为 char **,需要 char *** 来接收

char **p;
char ***rec = &p;

(2) char ***p

同理

2 指针数组

元素为指针的数组

p 本身是数组,而数组内部的元素是指针

先定义如下:

char c1 = 'a', c2 = 'b', c3 = 'c', c4 = 'd', c5 = 'e', c6 = 'f';
char *pc1 = &c1, *pc2 = &c2, *pc3 = &c3, *pc4 = &c4, *pc5 = &c5, *pc6 = &c6;

(1) char *p[]

char *p[] = {&c1, &c2, &c3};

 

重申一下!p 只是个数组(p表示数组的首地址),不能给 p 赋值(也不能指向任何东西)

比如,下面这样是错误的:

char array2[][4]= {&c1, &c2, &c3};
char *p[] = array;  // Error,p是数组(p表示数组的首地址),不能被赋值

但是这样可以(数组里面的元素是指针):

char array1[] = "a01";
char *p[3];
p[0] = array1;

puts(p[0]);    // “a01”

如果需要传递多维数组,请使用数组指针

参数传递

对于上述 p ,首先 p 是一维数组,同时因为 p 中的元素为也就是 p[0] 的数据类型为 char * ,那么 p 的数据类型即为 char **

同时因为 p 自身是数组,所以 rec 的数据类型需与 p 一致,也必须为 char **

char *p[] = {&c1, &c2, &c3};
char **rec = p;

(2) char *p[][3]

n行3列的指针数组

p 是一个二维数组,维度为 (n x 3),数组中每个元素为 char 型

注:多维数组在定义时,列数必须确定

以2行3列举例:

char *p[][3] = { 
                 {&c1, &c2, &c3},
                 {&c4, &c5, &c6},
               };

 

参数传递

(1) 对于上述 p ,首先 p 是二维数组,同时因为 p 中的元素为也就是 p[0][0] 的数据类型为 char * ,那么 p[0] 的数据类型即为 char **,而这些都是对于一维数组来说的(不需要维度约束),而对于 p ,因为是二维数组(需要进行维度约束),且数组中每一个元素也就是p[0][0]为 char *,所以需要将本来的 char *** 转化为 char * (*)[3]。

太麻烦了,换一种方式

(2) 对于上述 p ,首先 p 是一个二维数组,且维度为 (2 x 3),所以有 char (*)[3],又因为二维数组内的元素为 char *,所以 p 的数据类型为 char * (*)[3]

同时因为 p 自身是数组,所以 rec 的数据类型也必须为 char * (*)[3]

char *p[][3] = { 
                 {&c1, &c2, &c3},
                 {&c4, &c5, &c6},
               };
char * (*rec)[3] = p;

(3) char **p[][3]

原理同上

char **p[][3] = { 
                 {&pc1, &pc2, &pc3},
                 {&pc4, &pc5, &pc6},
                };

 

参数传递

对于上述 p ,首先 p 是一个二维数组,且维度为 (2 x 3),所以有 char (*)[3],又因为二维数组内的元素为 char **,所以 p 的数据类型为 char ** (*)[3]

同时因为 p 自身是数组,所以 rec 的数据类型也必须为 char ** (*)[3]

【补充】:

p[0] 的数据类型:char *** (p[0] 为一维数组,不需要维度约束)

p[0][0] 的数据类型:char ** 

p[0][0][0] 的数据类型:char *

char **p[][3] = { 
                 {&pc1, &pc2, &pc3},
                 {&pc4, &pc5, &pc6},
                };
char ** (*rec)[3] = p;

3 数组指针

指向数组的指针

不过这种概念正常只用于维度 >= 2 的数组

(1) char (*p)[4]

p是一个指针,指向一个二维数组,该二维数组的维度为:(n x 4),二维数组的元素为 char 型变量。

举例,n == 3

【注】:此处 [ ] 内的数字不能省略,必须确定除最外侧的所有内侧的维度。 eg: char (*p)[1][2][3]  <—— 都必须指定

 

char array2[][4] = {"a01",     // (3 x 4)
                    "a02", 
                    "a03"};    
char (*p)[4] = array2;

或

char (*p)[4];
p = array2;

【注】:p 是一个指针,一次只能被赋予一个元素,像下面这样就是错误的:

char (*p)[4] = {"a01", "a02", "a03"};    // Error

参数传递

对于上述 p ,因为 p 本身就是指针,所以直接去掉变量名即可得到数据类型:char (*)[4]

同时因为 p 自身是指针,所以 rec 的数据类型必须为 char (**)[4]

char (**rec)[4] = &p;

补充:*p 的数据类型为:char *

(2) char (*p)[3][4]

p 是一个指针,指向一个三维数组,该三维数组的维度为:(n x 3 x 4),数组中的元素为 char 型

举例,n == 2

char array3[][3][4] = {	// (2 x 3 x 4)						 
						{"a01", "a02", "a03"},
						{"b01", "b02", "b03"},
					 };
char (*p)[3][4] = array3;

参数传递

对于上述 p ,因为 p 本身就是指针,所以直接去掉变量名即可得到数据类型:char (*)[3][4]

同时因为 p 自身是指针,所以 rec 的数据类型必须为 char (**)[3][4]

char (**rec)[3][4] = &p;

补充:

*p 的数据类型为:char (*)[4]

*(*p) 的数据类型为:char *

(3) char * (*p)[3]

p是一个指针,指向一个二维数组,该二维数组的维度为:(n x 3),二维数组的元素为指针。

举例,n == 2

 

char *array4[][3] = {	 // (2 x 3 x 4)				 
						{&c1, &c2, &c3},
						{&c4, &c5, &c6},
					};
char * (*p)[3] = array4;

 

参数传递

对于上述 p ,因为 p 本身就是指针,所以直接去掉变量名即可得到数据类型:char * (*)[3]

同时因为 p 自身是指针,所以 rec 的数据类型必须为 char * (**)[4]

char * (**rec)[3] = &p;

补充:

*p 的数据类型为:char **

*(*p) 的数据类型为:char *

(4) char (**p)[4]

指向 [ 指向数组的指针 ] 的指针

p 是一个指针,其所指的对象为一个指针,而该指针指向一个二维数组,该二维数组的维度为:(n x 4),二维数组的元素为 char 型变量。

举例,该二维数组维度为:(3 x 4)

char array2[][4] = {"a01",     // (3 x 4)
                    "a02", 
                    "a03"};  
char (*t)[4] = array2;
char (**p)[4] = &t;

参数传递

对于上述 p ,因为 p 本身就是指针,所以直接去掉变量名即可得到数据类型:char (**)[4]

同时因为 p 自身是指针,所以 rec 的数据类型必须为 char (***)[4]

char (***rec)[4] = &p;

补充:

*p 的数据类型为:char (*)[4]

*(*p) 的数据类型为:char *

4 数组指针数组

元素为 [ 指向数组的指针 ] 的数组

(1) char (*p[])[4]

p是一个数组,其中每个元素等于 3(1) 

换句话说,像这样的 p:char (*p)[4],给我多来几个

比如来俩

char array21[][4] = {"a01", "a02", "a03"};    // (3 x 4)
char array22[][4] = {"b01", "b02", "b03"};    // (3 x 4)
char (*p[])[4] = {array21, array22};

或

char (*p[2])[4];
p[0] = array21;
p[1] = array22;

【注】:与3(1)同理,下面这样是错误的:

char (*p[])[4] = {     // Error
                    {"a01", "a02", "a03"},
                    {"b01", "b02", "b03"},
                  };     

参数传递

对于上述 p ,因为 p 中元素为二维数组,且维度为 (3 x 4) 也就是说 p[0] 的数据类型为 char (*)[4] ,那么 p 的数据类型即为 char (**)[4]

同时因为 p 自身是数组,所以 rec 的数据类型也必须为 char (**)[4]

char (**rec)[4] = p;

补充:

p[0] 的数据类型:char (*)[4]

p[0][0] 的数据类型:char *

p[0][0][0] 的数据类型:char

 

(2) char (*p[])[3][4]

p是一个数组,其中每个元素等于 3(2) 

换句话说,像这样的 p:char (*p)[3][4],给我多来几个

比如来俩

char array31[][3][4] = {	// (2 x 3 x 4)						 
						  {"a01", "a02", "a03"},
						  {"b01", "b02", "b03"},
					   };
char array32[][3][4] = {	// (2 x 3 x 4)						 
						  {"c01", "c02", "c03"},
						  {"d01", "d02", "d03"},
					   };
char (*p[])[3][4] = {array31, array32};

参数传递

对于上述 p ,因为 p 中元素为三维数组,且维度为 (2 x 3 x 4) 也就是说 p[0] 的数据类型为 char (*)[3][4] ,那么 p 的数据类型即为 char (**)[3][4]

同时因为 p 自身是数组,所以 rec 的数据类型也必须为 char (**)[3][4]

 

char (**rec)[3][4] = p;

补充:

p[0] 的数据类型:char (*)[4]

p[0][0] 的数据类型:char *

p[0][0][0] 的数据类型:char

(3) char * (*p[])[3][4]

同理,参考3(3)和4(2)

(4) char * (*p[][2])[3][4]

同理

char *array31[][3][4] = {	// (2 x 3 x 4)						 
						  {{&c1, &c2, &c3, &c4}, {&c1, &c2, &c3, &c4}, {&c1, &c2, &c3, &c4}},
						  {{&c1, &c2, &c3, &c4}, {&c1, &c2, &c3, &c4}, {&c1, &c2, &c3, &c4}},
					    };
char *array32[][3][4] = {	// (2 x 3 x 4)						 
						  {{&c1, &c2, &c3, &c4}, {&c1, &c2, &c3, &c4}, {&c1, &c2, &c3, &c4}},
						  {{&c1, &c2, &c3, &c4}, {&c1, &c2, &c3, &c4}, {&c1, &c2, &c3, &c4}},
						};
char *array33[][3][4] = {	// (2 x 3 x 4)						 
						  {{&c1, &c2, &c3, &c4}, {&c1, &c2, &c3, &c4}, {&c1, &c2, &c3, &c4}},
						  {{&c1, &c2, &c3, &c4}, {&c1, &c2, &c3, &c4}, {&c1, &c2, &c3, &c4}},
					    };
char *array34[][3][4] = {	// (2 x 3 x 4)						 
						  {{&c1, &c2, &c3, &c4}, {&c1, &c2, &c3, &c4}, {&c1, &c2, &c3, &c4}},
					      {{&c1, &c2, &c3, &c4}, {&c1, &c2, &c3, &c4}, {&c1, &c2, &c3, &c4}},
						};
char * (*p[][2])[3][4] = { 
                            {array31, array32},
							{array33, array34},
						 };

参数传递

对于上述 p ,因为 p 中元素为三维数组,且维度为 (2 x 3 x 4),故 p[0][0] 的数据类型应为 char (*)[3][4],又因为该三维数组的子元素也就是 p[0][0][0][0][0] 的数据类型为 char *,故 p[0][0] 的数据类型应为 char * (*)[3][4]

又因为 p 自身是二维数组,则 p[0] 的数据类型为:char * (**)[3][4],故 p 的数据类型为 char * (* (*)[2])[3][4]

所以 rec 的数据类型也必须为 char * (* (*)[2])[3][4]

char  (*(*rec)[2])[3][4] = p;

补充:

p[0] 的数据类型:char * (**)[3][4]

p[0][0] 的数据类型:char * (*)[3][4]

p[0][0][0] 的数据类型:char * (*)[4]

p[0][0][0][0] 的数据类型:char **

p[0][0][0][0][0] 的数据类型:char *

5 指针数组指针

参考第 2 章中的参数传递,接收变量 rec 皆为指针数组指针

6 函数指针

指向函数的指针

定义:函数返回值类型 (* 指针变量名) (函数参数列表);

如:char (*pfun)(int);

定义了一个指针变量 pfun,该指针变量可以指向返回值类型为 char 型,且有一个整型参数的函数。

pfun 的数据类型为: int(*)(int)

char fun(int x)
{
    return x % 256;
}

char (*pfun)(int);    // 声明

pfun = fun;

(*pfun)(1234);    // 调用

或使用 typedef 声明

typedef char (*pFUN)(int);    // 声明数据类型

pFUN pfun;
pfun = fun;
(*pfun)(1234);    // 调用

参数传递

因为 pfun 的数据类型为: char (*)(int,int),且 pfun 为指针,所以 rec 的数据类型必须为:char (**)(int,int)

char (**rec)(int, int) = &pfun;

函数指针数组

例如:char (*pfun[])(int)

像这样的函数指针 pfun:char (*pfun)(int),给我多来几个

比如来俩

char fun1(int x)
{
    return x % 256;
}
char fun2(int y)
{
    return y % 256;
}

char (*pfun[])(int) = {fun1, fun2};

或

char (*pfun[])(int);
pfun = {fun1, fun2};

返回类型为函数指针的函数

return_type(*function(func_parameter_list))(parameter_list)

例如:char (*fun(int))(int)

函数 fun(int) 的返回值为一个函数指针,数据类型为: char (*)(int)

char (*fun3(int x))(int)
{
	if(x > 2)
		return fun1;
	else
		return fun2;
}

7 指针函数

返回值为指针的函数

如:char * fun(int, int);

 

8 练习

说了这么多,举几个了例子练习一下

(1) 有一次,一个程序员与我交谈一个问题。他当时正在编写一个独立运行于某种微处理器上的C程序。当计算机启动时,硬件将调用首地址为 0 位置的子例程。为了模拟开机启动的情形,我们必须设计出一个C语句,以显示调用该子例程。(节选自《C陷阱与缺陷》)

对于该问题,分析 “调用地址0位置的子例程” ,如果直接:
 
(*0)()
这样做并没有什么用,因为运算符 * 只能对指针进行操作,那么首先需要将 0 转换为一个函数地址,也就是数据类型为函数指针,返回值为void的函数指针的数据类型为:void (*)(),那么对 0 进行数据类型转换:
 
(void (*)())0
然后对其进行调用:
 
(*(void (*)())0)()
更清晰的写法是使用 typedef 来声明
 
typedef void (*pfun)();
(*(pfun)0)();

(2) 在信号处理头文件 signal.h 中有一个库函数 signal,该函数接收两个参数,一个代表设置处理功能的信号值(整型),另一个是对应信号的处理函数(函数指针)(节选自《C陷阱与缺陷》)

函数声明为:

void (*signal(int sig, void (*handler)(int)))(int)

signal后面紧跟括号代表其并非函数指针,而是一个函数,参数列表为 ( int sig, void (*handler)(int) ),第一个参数为 int 型,第二个参数为函数指针: void (*handler)(int)

然后结合 void (* 函数signal )(int),可知,函数 signal 的返回值是一个函数指针,数据类型为:void (*)(int)   (该数据类型与 signla 的第二个参数的数据类型相同)

可使用 typedef 对该声明进行简化(选自 glibc 中 signal 源码)

typedef void (*__sighandler_t)(int);
__sighandler_t signal (int sig, __sighandler_t handler)

 

 

参考

《C专家编程》

《C陷阱与缺陷》

Signal ()函数用法和总结

signal源码

 

 

 

uniapp(微信小程序) - 实现uniapp小程序电子签名板,横屏手写姓名签名专用写字画板,客户专用签字板,手写签名签字画板组件,手写签名,(详细运行示例,一键复制开箱即用) uniapp实现微信小程序的电子签名效果,uniapp微信小程序 电子签名 写字板,用uniapp实现微信小程序的电子签名,uniapp微信小程序canvans实现手写签名,记录一个uniapp写的小程序的手写板,横屏,用于签名,unniapp实现电子签名,uniapp怎么做横屏的手写签名,uniapp如何实现签字板,uniapp小程序平台下怎么做电子签名板组件,uniapp电子签名插件,uniapp最好用的电子写字板插件组件源码,实现uniapp 手写签名功能,手写板、签字板,uni-app插件市场最好的 阅读详情

相关推荐

未隔离电源设备使用usb转串口调试导致串口模块爆炸烧坏事故记录

这个事就发生在前两天,我们公司的wifi模块被客户用到了咖啡机上,客户寄了一台整机给我们协助调试,还送了几包咖啡豆,本想着还能打个咖啡喝一喝的,但就在咖啡机刚寄过来第一天,就出事了。而这个事故的发生,竟然仅仅是因为同事接了个串口模块到电脑调试打印导致的。谁也想不到,这个3.3V的供电的wifi模块居然还有这么大的威力。直接将usb转TTL串口模块的转换芯片给爆开了,咖啡机也给弄坏了,据同事描述当时情况就只见到一片火光和一声巨响,状况比较惨烈,所幸的是笔记本电脑没有烧坏,但是直接给崩蓝屏了。 ...

fangye945a的博客 6197

数组指针

数组指针 格式: char (*p)[3]; int (*q)[3]; 含义: 它是一个指针,执行一个二维数组 赋值: int (*q)[3]; int a[4][3]; q = a; 理解的方法:把a[4]看成一个整体, 由于a[i] = p[i] = *(a+i) = *(p+i); 所以它和*p是一样的,那a[][3] = (*p)[3] 即q = a; 总结: a[i][j] <====> *(a[i]+j) &l.

Linux_zhicheng的博客 222

信贷风控实战指南:Vintage分析表从数据建模到风险洞察

本文是一份信贷风控实战指南,详细阐述了Vintage分析从数据建模到风险洞察的全流程。文章深入解析了Vintage分析作为信贷资产“体检报告”的核心价值,并提供了从借据表与还款计划表设计、账龄计算、逾期口径判定到风险暴露计算与最终可视化透视的完整SQL实现方案,旨在帮助风控从业者构建精准的风险监控体系。

nft7creator的博客 321

C语言入门必做踩坑题《篇三》

第1题 ????设有定义 char *p[ ] = {“Shanghai”, Beijing", “Hongkong”}; 则结果为 j 字符的表达式是 ( ) A. *p[1] + 3 B. *(p[1] + 3) C. *(p[3] + 1) D. p[3][1] ???? 分析: 此题是对指针数组的考察,对于上面的定义我们可以画出如下关系图 对于这段代码必须得理解这张图,否则你对这个代码的理解是有问题的,此外还需要了解运算符之间的优先级 所以选择 B 选项 第2题 ????执行以下函数后, i 的

DanceBit的博客 1万+

Kubernetes集群环境搭建与初始化

Kubernetes是Google开源的一个容器编排引擎,它支持自动化部署、大规模可伸缩、应用容器化管理。在生产环境中部署一个应用程序时,通常要部署该应用的多个实例以便对应用请求进行负载均衡。在Kubernetes中,我们可以创建多个容器,每个容器里面运行一个应用实例,然后通过内置的负载均衡策略,实现对这一组应用实例的管理、发现、访问,而这些细节都不需要运维人员去进行复杂的手工配置和处理。

m0_75254642的博客 1526

告别理论劝退:用动画和Tanner图轻松理解QC-LDPC的译码原理(BP算法详解)

本文通过动画和Tanner图直观解析QC-LDPC码的BP译码原理,帮助读者轻松理解802.11ac协议中的编译码过程。文章详细展示了QC-LDPC的结构之美、BP算法的动态信息流动以及LLR的视觉化解读,并对比了硬判决算法的性能差异,为开发者和研究者提供了实用的可视化工具开发建议。

weixin_30411239的博客 493

右左法则 转

C指针声明解读之左右法则2008-06-03 08:46   C语言所有复杂的指针声明,都是由各种声明嵌套构成的。如何解读复杂指针声明呢?右左法则是一个既著名又常用的方法。不过,右左法则其实并不是C标准里面的内容,它是从C标准的声明规定中归纳出来的方法。C标准的声明规则,是用来解决如何创建声明的,而右左法则是用来解决如何辩识一个声明的,两者可以说是相反的。右左法则的英文

一草一木的专栏 951

光伏发电预测(LSTM、CNN_LSTM和XGBoost回归模型,Python代码)

一旦结果与预测差距较大,可能存在光伏系统的问题,需要找出原因,然后采取适当措施来修复光伏系统并做出更好的决策。例如,根据准确的预测,光伏系统运营商可以平衡电力消耗,并将多余的电力储备用于紧急情况。然而,光伏系统的发电量估算是一个挑战,因为光伏系统的发电量受到天气条件的极大影响。整个项目文件夹(第一个文件夹为xgboost模型相关的包文件,xg.py是xgboost模型英文注释版本,xg_chinese.py是xgboost模型中文注释版本)表示空气的温度,通常以摄氏度(°C)或华氏度(°F)为单位。

2301_79699110的博客 3034

c语言-指针

​C语言里,变量存放在内存中,而内存其实就是一组有序字节组成的数组,每个字节有唯一的内存地址。CPU通过内存寻址对存储在内存中的某个指定数据对象的地址进行定位。这里,**数据对象是指存储在内存中的一个指定数据类型的数值或字符串,它们都有一个自己的地址,而指针便是保存这个地址的变量。指针是一种保存变量地址的变量。​ 前面已经提到内存其实就是一组有序字节组成的数组,数组中,每个字节大大小固定,都是8bit。对这些连续的字节从0开始进行编号,每个字节都有唯一的一个编号,这个编号就是内存地址。

weixin_45652283的博客 810

(三十九)Flask 多应用架构(Multiple Apps)与 DispatcherMiddleware 实战解析

(三十九)Flask 多应用架构(Multiple Apps)与 DispatcherMiddleware 实战解析

孤寒者的博客 1万+

YOLO格式数据集划分

YOLO格式的数据集划分 标题标签格式txt import os import cv2 import random from PIL import Image # os.makedirs('labels_train') # os.makedirs('labels_val') img_train_path ='./img_train/' #图片训练集保存路径 img_val_path = './img_val/' #图片验证集保存路径 labels_train_path = './labels_t

weixin_51154380的博客 3308

指针的详解

指针有:整形指针 int* p 字符指针 char* p 字符数组指针 char (*p)[3] 整形数组指针 int(*p)[3] 二级指针 int **p * 如何区分·数组指针和 指针数组? 举个例子 你是个好人 ,你是好 还是人呢? 数组...

qq_54732591的博客 235

从理论到实践:AI设备维护系统的架构实现

第一部分:理论基石——从设备维护的演进讲起,理解AI如何重塑维护模式;第二部分:架构设计——详解六层高可用系统架构,明确各层职责与技术选型;第三部分:核心技术——拆解数据处理、特征工程、模型训练、部署等关键环节的实现细节;第四部分:实践落地——8步流程带你从需求到上线,附代码示例与工具链;第五部分:案例研究——风电齿轮箱预测性维护系统的真实案例,从问题到方案再到效果;第六部分:挑战与展望——探讨当前技术瓶颈与未来趋势(数字孪生、联邦学习等)。准备好了吗?

大数据洞察的博客 1252

指针 浅析

c 的那点就在指针,它给user 的权限太大。 以一个例子开始: strcut test_t { int a; char b; int c; }; char *p; int *p1; struct test_t *p2; printf("%d",sizeof(p)) ==> 输出为 4 printf("%d",sizeof(*p) ==> 输出为 1 printf("%d",sizeof(p1)) ==> 输出为 4 pr...

sdc20102010的博客 193

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

浅析this指针

this指针是一个自引用指针,通常用于指向对象自身。本文将深度探讨this指针的核心特性、注意要素、应用场景和相关案例。

螺蛳粉只吃炸蛋的走风的博客 962

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

浅析指针与数组

(2)对指针使用sizeof运算符得到的是指针的长度(64位系统中为8),而对数组(名)使用sizeof的得到的是整个数组的长度,在这种情况下C/C++不会将数组名解释为地址。指针存放的是一个地址,给指针分类型,目的是告诉编译器取数据的规则,如整型指针则到指针存放的地址处取4个字节数据,指针型指针则到指针存放的地址处取8个字节数据。(1)指针是保存地址的变量,本质上是变量,可以作为左值被修改,而数组名是数组第一个元素的地址,本质上是常量,不可以作为左值被修改。指针:指针是一种保存地址的变量。

m0_52013334的博客 1804

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

浅析c指针

一.指针的定义 c语言中指针用变量前加‘*’号来表示,指针只是内存地址,并没有什么特殊之处。 定义:如 int *pv;   定义了一个整形指针变量,用来存储整数的内存地址。 赋值:int num;pv=&num; 将变量num的内存地址赋值给pv. 访问变量的值:两种方法,第一种直接使用变量名num来使用num中的值这叫直接访问;第二种使用 指针*pv来获取num中的值这叫间接访问。(

LH2HA3的博客 342

《浅析指针》

各位帅哥靓女们,猪猪又来写文章了(水文章),今天我们要说的就是c语言中被认知为最难的指针,为啥是最难,因为你把握不住啊。老规矩觉得猪猪写的还算不错的话,还请各位一件三连走起,如果猪猪写的有啥子问题,还请位于评论区斧正。 【一】何为指针? 啥是指针?当一个数据需要存入空间的时候,内存中会相应开辟空间,你总不能把数据直接丢进去直接完事,你需要记住把他丢哪里了,这样方便你下次去找到他。而你记录的就是地址,其实你类比于日常生活中是非常好理解的,因为 ...

wuqin668的博客 295

[iOS]浅析isa指针

[iOS]浅析isa指针

m0_74703932的博客 1322

浅析C指针

C语言中的指针实质是指向某一对象的内存地址,对象可以是变量、常量、数组、函数等。不同类型的指针大小是不变的,例如在64位操作系统中,指针大小占8个字节。可以对地址进行前移、后移运算;可以通过运算符获取内存地址保存的数据。操作系统大小(字节)备注62位8int*、float*、char*等指针大小均为8字节32位4int*、float*、char*等指针大小均为4字节。

FranzLiszt的博客 500

浅析C++的指针与引用

引用的使用可以一定程度避免“指针满天飞”的情况,对于提升程序稳定性也有一定的积极意义。同时指针与引用底层实现都是一样的,不用担心两者的性能差距。

螺蛳粉只吃炸蛋的走风的博客 1531

浅析C++中的this指针

     有下面的一个简单的类:class CNullPointCall{public:    static void Test1();    void Test2();    void Test3(int iTest);    void Test4();private:    static int m_iStatic;    int m_iTest;};int CNullPointCal

寒星轩 6万+

浅析C++this指针

什么是this指针? this指针的作用是什么? this指针有哪些特性? this指针传参方式? 为什么叫this指针而不是引用呢? this指针有没有可能为空? this指针容易混淆点 1) 什么是this指针? this是指向实例化对象本身时候的一个指针,里面存储的是对象本身的地址,通过该地址可以访问内部的成员函数和成员变量。举例来说:当你进入一个房子后,你可以看见桌子、椅子、地板等,...

番茄都是西红柿 1650

浅析指向指针的指针其作用

这篇文章主要是介绍 指向指针的指针 的一种用法 所以这里不谈指针或指向指针的指针他们的基础 直接上代码(用途:使用一个函数动态申请内存,并赋值。跳出调用函数后输出赋值内容) #include #include typedef struct Data { int da; } Data; void fun(Data *p); int main() { Data

学无止境 1909

C++基础之指针浅析

C++指针浅析指针的基本概念指针变量的定义和使用指针所占内存空间空指针和野指针const修饰指针指针和数组指针和函数指针,数组,函数 指针的基本概念 内存编号从0开始记录,一般是用十六进制数字表示 同时,也可以利用指针变量保存地址 指针的作用 : 可以通过指针间接访问内存 指针变量的定义和使用 语法 : 数据类型 * 变量名; #include <iostream> using namespace std; int main(){ int a = 10; //指针

lovelyGFR的博客 253
上一篇: 实现链表与哈希表相结合的快速表
下一篇: 实现自定义的数据结构 —— 自然树
且听风吟0618
博客等级 码龄11年 150粉丝 25原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值