[英]Why is my struct pointer creating function returning NULL because of a local declaration?
[英]Why is my function not returning null pointer?
我的可视化代码有问题,在线编译器上一切正常,但是在 stm32 核上尝试时,它不返回NULL
,问题出在哪里? 它不能打破while
循环。
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
int funk(char *skai) {
char delim[] = "+-=";
int i = 0;
float x, d = 0;
char *array[2];
char *ptr = strtok(skai, delim);
while (ptr != NULL) {
array[i++] = ptr;
ptr = strtok(NULL, delim); // <---- doesnt return null, endless loop
}
int a = atoi(array[0]);
float b = atof(array[1]);
int c = atoi(array[2]);
if (c != 0) {
d = b * b - 4 * a * c;
if (d > 0) {
float root1 = (-b + sqrt(d)) / (2 * a);
float root2 = (-b - sqrt(d)) / (2 * a);
if (root1 > root2) {
x = root1;
} else {
x = root2;
}
} else {
x = -b / (2 * a);
}
} else {
x = b / a;
} //printf("%0.3f\n", x);
return x;
}
int main(void) {
char rxd[20] = "2x^2+x/5+2=0";
funk(rxd);
}
给定skai
指向包含“2x+2=0”的char
数组,使用分隔符“+-=”对strtok
的调用序列预计首先返回指向“2x”(第一个字符)的指针,然后“ 2”,然后是“0”,然后是空指针。 编写的代码尝试将这些值存储在array[0]
、 array[1]
和array[2]
。 但是, array
没有元素 2,因为它只定义了两个元素。 所以程序溢出了数组,程序的结果行为并没有被 C 标准定义。 可能是程序然后以导致strtok
行为不端的方式覆盖内存。
将array
的定义更改为更大,并在调用strtok
的循环内监视i
的值:如果达到数组大小的限制,则打印错误消息并终止函数(或整个程序)。
您的程序有多个问题:
strtok()
修改其第一个参数指向的字符串,这是一个令人讨厌的副作用,并且在您的情况下会丢失重要信息,例如下一个常量的符号。/
array
只有 2 个条目,导致大多数具有更多项的方程的未定义行为。 这是使用strtod()
和手动解析的修改版本:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int funk(const char *exp, double *x1, double *x2) {
double coef[3] = { 0, 0, 0 };
double d, e, a, b, c, sign, part;
int n;
const char *p = exp;
char *q;
part = 1;
for (;;) {
p += strspn(p, " \t\r\n"); // skip whitespace
if (!*p)
break;
if (*p == '=') {
p++;
if (part < 0)
return -1;
part = -1;
continue;
}
d = 1;
sign = part;
if (*p == '+') {
p++;
} else
if (*p == '-') {
sign = -1;
p++;
}
if (*p != 'x') {
d = strtod(p, &q);
if (p == q)
return -1;
p = q;
}
d *= sign;
n = 0;
if (*p == '/') {
p++;
e = strtod(p, &q);
if (p == q)
return -1;
p = q;
d /= e;
}
if (*p == 'x') {
p++;
n = 1;
if (*p == '^') {
p++;
n = strtol(p, &q, 10);
if (p == q)
return -1;
p = q;
if (n < 0 || n > 2)
return -1;
}
}
if (*p == '/') {
p++;
e = strtod(p, &q);
if (p == q)
return -1;
p = q;
d /= e;
}
coef[n] += d;
}
a = coef[2];
b = coef[1];
c = coef[0];
d = b * b - 4 * a * c;
if (a > 0 || a < 0) {
/* quadratic equation */
if (d < 0) {
return -2;
} else
if (d > 0) {
*x1 = (-b + sqrt(d)) / (2 * a);
*x2 = (-b - sqrt(d)) / (2 * a);
return 2;
} else {
*x1 = -b / (2 * a);
return 1;
}
}
if (b < 0 || b > 0) {
/* first order equation */
*x1 = 0 + -c / b;
return 1;
}
/* constant equation */
if (c > 0 || c < 0) {
return 0;
} else {
return 3;
}
}
void solve(const char *exp) {
double x1, x2;
switch (funk(exp, &x1, &x2)) {
case 0:
printf("%s -> no solution\n", exp);
break;
case 1:
printf("%s -> single root x=%g\n", exp, x1);
break;
case 2:
printf("%s -> two roots x1=%g, x2=%g\n", exp, x1, x2);
break;
case -2:
printf("%s -> two imaginary roots\n", exp);
break;
case 3:
printf("%s -> true for all x\n", exp);
break;
default:
printf("not a quadratic equation: %s\n", exp);
break;
}
}
int main(int argc, char *argv[]) {
if (argc > 1) {
for (int i = 1; i < argc; i++)
solve(argv[i]);
} else {
solve("2x^2+x/5+2=0");
solve("x^2+2x+1=0");
solve("x^2=49");
solve("x=49");
solve("x=0");
solve("2=2");
solve("1=0");
}
return 0;
}
阵列太小 - 两个。 *1
我使array[]
大得多并添加了printf("%d '%s'\\n", i, ptr)
char *array[20];
char *ptr = strtok(skai, delim);
while (ptr != NULL) {
printf("%d '%s'\n", i, ptr);
array[i++] = ptr;
ptr = strtok(NULL, delim); // <---- doesnt return null, endless loop
}
输出是
0 '2x^2'
1 'x/5'
2 '2'
3 '0'
所以显然array[]
至少需要是array[4]
。
建议在解析时添加保护或使用不同的方法。
if (i+1 >= sizeof array/sizeof array[0]) {
// Handle/report error somehow
}
array[i++] = ptr;
旁白:如果使用float
变量,不妨使用float
函数。
// float root1 = (-b + sqrt(d)) / (2 * a);
// ---------------------v
float root1 = (-b + sqrtf(d)) / (2 * a);
*1
帖子已从"2x+2=0"
更改为"2x^2+x/5+2=0"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.