(*(void(*)(int))0)(int)与void(single(void(*)(int))(int))(int)详解

  哈楼大家好啊!今天给大家讲一下在一些复杂的代码中出现的一些代码的解释他们分别是(*(void(*)(int))0)(int)void(sigture(void(*)(int))(int))(int)

看着是不是很头大,没关系啊下面我详细的介绍一下他们。

目录

一.(*(void(*)(int))0)(int)

二.void(*single(void(*)(int),int))(int)


一.(*(void(*)(int))0)(int)

首先还是从简单的说起首先我们先将这一串代码拆分一下:

首先void(*)(int)这个是不是很眼熟如果还没有看出来的话子啊看一下这个:int(*p)(int)这样的话是不是就顺眼多了没错他就是一个函数指针类型。那他外面再加一个括号是什么呢?并且后买你还加了一个‘0’.其实我们仔细回顾一下我们学过的知识他是不是很像一个强制类型转换,那么(void(*)(int))0这段代码的意思就是将0强制转化为void(*)(int)这个类型。

那括号前面的那一个*号就是解引用了,最外面括号外面还有一个(int),那这个是不是就有点咸一个函数调用了呢?

我们举一个例子相信大家肯定更容易懂

#include<stdio.h>
void print(int x)
{
	printf("这个数字是%d\n", x);
}
int main()
{
	void (*test)(int) = print;
	test(1);
	int a = test;
	printf("这个函数的地址是%p\n", (void(*)(int))a);
	(*(void(*)(int))a) (2);
	return 0;
}

这个代码可以分为以下步骤来理解:

1.首先创建一个void(*)(int)类型的函数指针名为test,将print函数赋予test,由于函数名就代表函数的地址这可以通过test指针去调用这个函数最终打印出来的是1。

2.将test的值赋予a并将a强制转换为void(*)(int)类型并打印,这个地址就是函数print的地址,(注:由于每次打印print的地址都会该百年所以只能将test的地址赋予a,并强制转化a来解释)

3.最后来到我们要讲的这个代码首先void(*)(int)被括号括起来后面放一个a(这个a也是整形与0相仿)其实就是跟上面打印的时候相同为强制类型转换也就相当于test的地址,之后解引用并输入参数2调用。

大概就是这么个思路正如我们上面所说函数无论是他的&还是函数名都是他的地址,那是不是

前面那个*也可以去掉呢?答案是可以的,不信你们可以自己去试一下。

二.void(*single(void(*)(int),int))(int)

讲了比较简单的那个就来讲比较复杂的吧,看着这个是不是更复杂,他其实是一个函数的申明由于他不像函数调用可以执行就不去举例子了。

首先我们将这个代码拆分一下首先看signed里卖的那个void(*)(int)这个不就是上面讲的一个函数指针类型吗,后买还有一个int,我们不去想的那么复杂先将这个函数指针类型替换为“int”就变为single(int,int)这样是不是就明白了。

其实呢signed就是一个函数只不过参数是void(*)(int)而已,现在我们知道signed是一个函数名那我们就可以把他给去掉变为void(*)(int),哈哈,这不老熟人了吗?兄弟们熟不熟悉还是我们的函数指针那我们继续使用我们的老套路讲他变为“int”那这个就变为了int single(int,int)是不是逐渐明朗起来了。

现在可能有人会问了那single原本在void(*)(int)里面怎么到我这就到外面了呢?其实吧c语言规定这个类型创建时由于()的优先级要高于*所以只能用括号括起来了。那如果写成这样

void(*)(int)single(void(*)(int),int)这样是不是就明白了。

欧克了我们的介绍就到这里了,喜欢的兄弟们可以一键三连,欢迎大佬来指出错误qwq!!!

拜拜啦!

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
`Mat_VarWriteData()`函数用于将数据写入MATLAB格式的文件中的变量。 函数参数如下: - `mat`:`mat_t`类型的指针,指向要写入数据的MATLAB文件。 - `matvar`:`matvar_t`类型的指针,指向要写入数据的变量。 - `data`:`void`类型的指针,指向要写入的数据。 - `start`:`int`类型的指针,指向一个数组,包含要写入数据的起始位置。 - `stride`:`int`类型的指针,指向一个数组,包含要写入数据的步长。 - `edge`:`int`类型的指针,指向一个数组,包含要写入数据的大小。 函数返回值为`0`表示写入成功,否则返回错误代码。 以下是函数的详细用法: 1. 如果要写入的变量的数据类型是`MAT_C_SINGLE`或`MAT_C_DOUBLE`,则`data`指向的是一个二维数组(或一维数组)。 2. 如果要写入的变量的数据类型是`MAT_C_INT8`、`MAT_C_UINT8`、`MAT_C_INT16`、`MAT_C_UINT16`、`MAT_C_INT32`、`MAT_C_UINT32`、`MAT_C_INT64`或`MAT_C_UINT64`,则`data`指向的是一个一维数组。 3. `start`、`stride`和`edge`分别对应数据的起始位置、步长和大小。如果数据是二维数组,则`start`、`stride`和`edge`数组的长度为2;如果数据是一维数组,则`start`、`stride`和`edge`数组的长度为1。 4. 如果要写入的数据是二维数组,则`start`数组的第一个元素为行号,第二个元素为列号。如果要写入的数据是一维数组,则`start`数组的第一个元素为元素的位置。 5. `stride`数组用于指定每个维度的步长。如果要写入的数据是二维数组,则`stride`数组的第一个元素为列的步长,第二个元素为行的步长。如果要写入的数据是一维数组,则`stride`数组的第一个元素为元素的步长。 6. `edge`数组用于指定数据在每个维度上的大小。如果要写入的数据是二维数组,则`edge`数组的第一个元素为列的数量,第二个元素为行的数量。如果要写入的数据是一维数组,则`edge`数组的第一个元素为元素的数量。 7. 如果要写入的数据是一维数组,则`start`、`stride`和`edge`数组的长度为1。在这种情况下,`start`数组的第一个元素为元素的位置,`stride`数组的第一个元素为元素的步长,`edge`数组的第一个元素为元素的数量。 示例代码如下: ```c #include <stdio.h> #include <stdlib.h> #include "mat.h" int main() { mat_t *mat; matvar_t *matvar; double *data; int start[2], stride[2], edge[2]; int i, j; // 创建MATLAB文件 mat = Mat_Create("data.mat", NULL); if (mat == NULL) { printf("创建MATLAB文件失败!\n"); return 1; } // 创建一个双精度浮点数变量 matvar = Mat_VarCreate("myvar", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, edge, data, 0); if (matvar == NULL) { printf("创建变量失败!\n"); Mat_Close(mat); return 1; } // 初始化数据 data = (double *)malloc(4 * sizeof(double)); for (i = 0; i < 2; i++) { for (j = 0; j < 2; j++) { data[i * 2 + j] = i + j; } } // 写入数据 start[0] = 0; start[1] = 0; stride[0] = 1; stride[1] = 1; edge[0] = 2; edge[1] = 2; Mat_VarWriteData(mat, matvar, data, start, stride, edge); // 释放内存 free(data); Mat_VarFree(matvar); Mat_Close(mat); return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值