Arduino摇杆控制器坐标系旋转异常求助:指针使用是否有误?
问题分析与解决方案
没错,你的指针用法确实踩了C/C++里一个经典的坑,这就是导致输出始终为0,0的根本原因!
问题出在哪?
在你的rotate函数里,out是一个局部栈数组:
float out[] = { ... }; return out;
当函数执行完毕后,栈上的局部变量会被系统回收,返回的指针就变成了「悬空指针」——它指向的内存已经不属于你的程序了,读取这个地址的值是未定义行为(这里碰巧输出了0,0,换个环境可能会得到随机乱码或者直接崩溃)。
另外还要提一句:你调用rotate的时候少了个逗号!float(center) PI/2.0应该改成float(center), PI/2.0,不过这个语法错误编译器应该会报错,可能是你粘贴的时候漏了。
几种修复方案
方案1:使用静态数组(简单但要注意复用问题)
把out改成静态数组,这样它的内存会分配在全局区,函数结束后不会被释放:
float *rotate(float x, float y, float cx, float cy, float angle) { static float out[2]; // 静态数组,内存不会被回收 out[0] = cx + (x - cx) * cos(angle) - (y - cy) * sin(angle); out[1] = cy + (x - cx) * sin(angle) + (y - cy) * cos(angle); return out; }
⚠️ 注意:静态数组是全局共享的,如果你在多个地方同时调用rotate,会覆盖之前的结果,但Arduino是单线程程序,这个场景下没问题。
方案2:让调用者传入结果数组(更安全)
避免返回指针,而是让调用者提供一个数组来存储转换后的坐标:
void rotate(float x, float y, float cx, float cy, float angle, float *result) { result[0] = cx + (x - cx) * cos(angle) - (y - cy) * sin(angle); result[1] = cy + (x - cx) * sin(angle) + (y - cy) * cos(angle); } // 调用的时候这样写: void loop() { int x = analogRead(X_pin); int y = analogRead(Y_pin); int center = 512; float transformed[2]; rotate(float(x), float(y), float(center), float(center), PI/2.0, transformed); int tx = int(transformed[0]); int ty = int(transformed[1]); Serial.print(tx); Serial.print(","); Serial.println(ty); // 别忘了加换行,不然输出会挤在一起 }
方案3:用结构体返回结果(最清晰,推荐)
自定义一个结构体来存储坐标,这样代码可读性更高,也不用跟指针打交道:
// 定义坐标结构体 struct Point { float x; float y; }; Point rotate(float x, float y, float cx, float cy, float angle) { Point p; p.x = cx + (x - cx) * cos(angle) - (y - cy) * sin(angle); p.y = cy + (x - cx) * sin(angle) + (y - cy) * cos(angle); return p; } // 调用的时候: void loop() { int x = analogRead(X_pin); int y = analogRead(Y_pin); int center = 512; Point transformed = rotate(float(x), float(y), float(center), float(center), PI/2.0); int tx = int(transformed.x); int ty = int(transformed.y); Serial.print(tx); Serial.print(","); Serial.println(ty); }
额外小建议
- 别忘了在
setup()里初始化串口:Serial.begin(9600);,不然可能看不到输出。 - 如果你需要多次旋转不同角度,可以把角度变量提出来,方便调整。
内容的提问来源于stack exchange,提问作者Lorenzo Rivosecchi
相关产品推荐
相关产品推荐

