如何在C语言中实现Tensor函数无引号传入类Python数组格式?
在C语言中实现Python风格的Tensor数组传参方案
不用折腾汇编,靠C语言的宏和编译期特性就能实现类似Python的语法糖,核心思路是用宏把数组字面量转换成Tensor可以处理的内存结构,下面是具体可行的方案:
1. 基础实现:基于宏的语法糖
先定义Tensor的核心结构体,再用宏封装数组字面量的解析逻辑,让你能直接写Tensor([[1.0f,2.0f],[3.0f,4.0f]])这种形式。
步骤1:定义Tensor结构体
#include <stdlib.h> #include <string.h> #include <stdio.h> typedef struct { float* data; // 存储张量数据的连续内存 int dims[2]; // 维度信息(这里先实现二维,可扩展) int total_elements;// 总元素数 } Tensor; // 实际创建张量的底层函数 Tensor* create_tensor(float* data, int rows, int cols) { Tensor* t = malloc(sizeof(Tensor)); t->dims[0] = rows; t->dims[1] = cols; t->total_elements = rows * cols; t->data = data; return t; } // 辅助销毁函数 void destroy_tensor(Tensor* t) { free(t->data); free(t); }
步骤2:实现Tensor宏
利用GCC/Clang支持的typeof扩展(标准C可改用C11的_Generic适配),宏会自动计算数组维度、复制数据并创建Tensor:
#define Tensor(arr) ({ \ typeof(arr) _temp_arr = arr; \ int _rows = sizeof(_temp_arr) / sizeof(_temp_arr[0]); \ int _cols = sizeof(_temp_arr[0]) / sizeof(_temp_arr[0][0]); \ float* _data = malloc(_rows * _cols * sizeof(float)); \ for (int i = 0; i < _rows; i++) { \ memcpy(_data + i * _cols, _temp_arr[i], _cols * sizeof(float)); \ } \ create_tensor(_data, _rows, _cols); \ })
使用示例
int main() { // 直接传入数组字面量,和Python写法一致 Tensor* a = Tensor([[1.0f, 2.0f], [3.0f, 4.0f]]); // 验证数据 printf("Rows: %d, Cols: %d\n", a->dims[0], a->dims[1]); for (int i = 0; i < a->total_elements; i++) { printf("%.1f ", a->data[i]); } // 输出:Rows: 2, Cols: 2 | 1.0 2.0 3.0 4.0 destroy_tensor(a); return 0; }
2. 扩展:支持任意维度(进阶)
如果需要支持更高维度,可以用递归宏或预处理器技巧逐层计算每个维度的大小,最终把多维数组扁平化到连续内存中。比如通过宏展开时的类型推导,依次获取各维度长度,再循环复制数据。
3. 局限性说明
- 只能处理编译期已知的数组字面量,运行时动态生成的数组还是需要手动传入数据和维度。
- 依赖编译器扩展(如
typeof),如果要兼容标准C,需要用_Generic或者手动指定维度参数。 - 示例默认是float类型,要支持int/double等类型,需要在宏里添加类型转换逻辑,或者用泛型宏适配。
内容的提问来源于stack exchange,提问作者Nevermnd
相关产品推荐
相关产品推荐

