在本学期我们正在使用C语言进行编程,在我们的第一个作业中,我们被要求使用手动和库实现来打印sin(x),cos(x)和tan(x)的值列表。所以,我写了下面的代码:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define START 0
#define STOP 360
#define STEP 10
#define PI 3.14159265358979323846 /*For conversion: degrees <-> radians */
double rad(double x); /* Converts angle in degrees to radians */
double next_term(double angle, int term_index);
/* Function prototypes for manual implementation of sin(x), cos(x) and tan(x) */
double sin_series(double x);
double cos_series(double x);
double tan_series(double x);
int main() {
/* Creating and printing the table title:
** ==================================================================== */
char table_title[] = " n | ";
strcat(table_title, "sin series | sin library | ");
strcat(table_title, "cos series | cos library | ");
strcat(table_title, "tan series | tan library | ");
printf("%s \n", table_title);
/* ==================================================================== */
/* Creating and printing the line between the title and the table:
** ==================================================================== */
char* second_line = (char*)malloc((strlen(table_title) + 1) * sizeof(char));
for (int i = 0; i < strlen(table_title) - 1; i++) {
second_line[i] = '=';
}
second_line[strlen(table_title)] = '\0';
printf("%s \n", second_line);
/* ==================================================================== */
free(second_line);
/* Creating each line of the table and printing it:
** ==================================================================== */
for (int angle = 0; angle < 360; angle += 10) {
printf("%4i | ", angle);
printf("%10.5f | %11.5f | ",sin_series(angle), sin(rad(angle)) );
printf("%10.5f | %11.5f | ",cos_series(angle), cos(rad(angle)) );
printf("%10.5f | %11.5f | ",tan_series(angle), tan(rad(angle)) );
printf("\n");
}
return 0;
}
double rad(double x) {
return ((PI * x) / 180);
}
double next_series_term(double angle, int term_index) {
double result = 1.0;
for (int i = 0; i < term_index; i++) {
result *= angle;
result /= (i + 1);
}
return result;
}
unsigned long long factorial(int x) {
unsigned long long result = 1;
for (int i = 0; i < x; i++) {
result *= (i + 1);
}
return result;
}
double sin_series(double x) {
double result = 0;
if (x == 0 || x == 180 || x == 360) {
result = 0;
}
else {
for (int i = 0; i < 100; i++) {
/* Calculating the next term to add to result to increase precision.*/
double next_term = next_series_term(rad(x), 2*i + 1);
next_term *= pow(-1,i);
result += next_term;
}
}
return result;
}
double cos_series(double x) {
double result = 0;
if (x == 90 || x == 270) {
result = 0;
}
else {
for (int i = 0; i < 100; i++) {
/* Calculating the next term to add to result to increase precision.*/
double next_term = next_series_term(rad(x), 2*i);
next_term *= pow(-1,i);
result += next_term;
}
}
return result;
}
double tan_series(double x) {
return sin_series(x)/cos_series(x); //non-portable! searching for
// better solution
}
但是这个代码在使用gdb后发现返回0后会导致Segmentation故障并让我完全感到困惑。作为C和编程的新手,这让我感到困惑。请帮忙。
答案 0 :(得分:4)
此声明
char table_title[] = " n | ";
声明table_title
是八个字符的数组。当您将其他字符串附加到数组的末尾时,您将写出越界并拥有undefined behavior。
指定一个足够大的大小来容纳您需要的所有数据,或者用完整的字符串正确初始化它。
答案 1 :(得分:1)
table_title
你分配了一个字符串,所以sizof(table_title)
将无法保存你传递的整个字符串,因此访问数组越界是未定义的行为,可能会导致崩溃。
答案 2 :(得分:1)
你为什么使用table_title?没有必要。只需使用printf。
printf ("sin series | sin library | cos series | cos library | tan series | tan library | ");
您静态声明了table_title。 free()用于释放动态分配的内存。这样做吧。不会出现分段错误。
答案 3 :(得分:1)
好的,你可以使用printf作为
printf (
"sin series | sin library | " \
"cos series | cos library | " \
"tan series | tan library | ");
没有包装。试试这个。 :)