My teacher said that I must add two complex numbers using a complex type. And I must add these numbers in a function. How to do that? I create something like that, but I have warning when I use cppcheck
add.c:53:26: error: Uninitialized variable: a1 [uninitvar]
double complex z1 = a1 + b1*I;
^
add.c:57:26: error: Uninitialized variable: a2 [uninitvar]
double complex z2 = a2 + b2*I;
^
add.c:53:31: error: Uninitialized variable: b1 [uninitvar]
double complex z1 = a1 + b1*I;
^
add.c:57:31: error: Uninitialized variable: b2 [uninitvar]
double complex z2 = a2 + b2*I;
^
add.c:34:29: error: Uninitialized variable: c1 [uninitvar]
double complex csum1 = c1 + d1*I;
^
add.c:34:34: error: Uninitialized variable: d1 [uninitvar]
double complex csum1 = c1 + d1*I;
^
add.c:52:15: error: Uninitialized variable: p [uninitvar]
readZ(wz, p, q);
^
add.c:52:18: error: Uninitialized variable: q [uninitvar]
readZ(wz, p, q);
^
add.c:56:15: error: Uninitialized variable: r [uninitvar]
readZ(wz, r, s);
^
add.c:56:18: error: Uninitialized variable: s [uninitvar]
readZ(wz, r, s);
^
add.c:59:18: error: Uninitialized variable: t [uninitvar]
sumZ(p,q,r,s,t,u);
^
add.c:59:20: error: Uninitialized variable: u [uninitvar]
sumZ(p,q,r,s,t,u);
This is my code
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <math.h>
#include <complex.h>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
void readZ(FILE *wp, double *a, double *b)
{
char c;
assert(fscanf(wp,"%c%lg%c%lg%c%c",&c,a,&c,b,&c,&c));
}
int writeZ(FILE *wp, double complex z)
{
fprintf(wp, "%.2f, %.2f\n", creal(z), cimag(z));
return 1;
}
void sumZ(double *a1, double *a2, double *b1, double *b2, double *c1, double *c2)
{
*c1 = *a1 + *a2;
*c2 = *b1 + *b2;
}
int main (int argc, char *argv[])
{
FILE *wz, *wc;
double a1, a2, b1, b2, c1, d1;
double *p, *q, *r, *s, *t, *u;
double complex csum1 = c1 + d1*I;
if (argc != 3) {
printf("Wrong arguments number\n");
printf("I should run this way:\n");
printf("%s source result\n",argv[0]);
exit(1);
}
if( (wz= fopen(argv[1],"r")) == NULL) {
printf("Open error %s\n", argv[1]);
exit(1);
}
if( (wc= fopen(argv[2], "w")) == NULL) {
printf("Open error %s\n", argv[2]);
exit(2);
}
readZ(wz, p, q);
double complex z1 = a1 + b1*I;
writeZ(wc, z1);
printf("%.2f, %.2f\n", creal(z1), cimag(z1));
readZ(wz, r, s);
double complex z2 = a2 + b2*I;
printf("%.2f, %.2f\n", creal(z2), cimag(z2));
sumZ(p,q,r,s,t,u);
printf("%.2f, %.2f\n", creal(csum1), cimag(csum1));
return 0;
}
When I run my code like add.x data.txt result.txt I get a segmentation fault. He said that I can use references and pointers. I have no idea what I should do now.
There were a number of errors.
There were a lot of double *
pointer variables [that were unitialized]. They aren't really needed. main
can just pass down (e.g.) &a1
and &b1
. Just because you were told to use pointers doesn't [necessarily] mean that you have to use pointer variables.
Also, pointers as arguments to a function are only needed for return values. Others can just use variables that are "pass by value". This simpilifies things a bit.
I had to guess at the correct function calls, based on an analysis of the code to determine your exact intent.
Your code was still trying to use separate double
variables (e.g.) a1
and b1
to get z1
instead of using [mostly] double complex
variables everywhere.
Also, it appears that the argument order for the call to sumZ
were reversed.
Here's a version that is annotated with the bugs and fixes:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <math.h>
#include <complex.h>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
void
readZ(FILE *wp, double *a, double *b)
{
char c;
#if 0
assert(fscanf(wp, "%c%lg%c%lg%c%c", &c, a, &c, b, &c, &c));
#else
assert(fscanf(wp, "%c%lg%c%lg%c%c", &c, a, &c, b, &c, &c));
#endif
}
int
writeZ(FILE *wp, double complex z)
{
fprintf(wp, "%.2f, %.2f\n", creal(z), cimag(z));
return 1;
}
// NOTE: not a bug exactly, but to simplify, b1/b2 and c1/c2 can be passed by
// value -- otherwise, mark them with "const" (e.g. const double *b1)
#if 0
void
sumZ(double *a1, double *a2, double *b1, double *b2, double *c1, double *c2)
{
*c1 = *a1 + *a2;
*c2 = *b1 + *b2;
}
#endif
#if 0
void
sumZ(double a1, double a2, double b1, double b2, double *c1, double *c2)
{
*c1 = a1 + a2;
*c2 = b1 + b2;
}
#endif
#if 1
void
sumZ(double complex a1, double complex b1, double complex *c1)
{
*c1 = a1 + b1;
}
#endif
int
main(int argc, char *argv[])
{
FILE *wz;
FILE *wc;
double a1;
double a2;
double b1;
double b2;
// NOTE: with refactoring, these are now unused
#if 0
double c1;
double d1;
double *p;
double *q;
double *r;
double *s;
double *t;
double *u;
#endif
#if 0
double csum1;
double csum2;
#endif
// NOTE/BUG: c1 and d1 are _unitialized_
#if 0
double complex csum1 = c1 + d1 * I;
#else
double complex csum1;
#endif
if (argc != 3) {
printf("Wrong arguments number\n");
printf("I should run this way:\n");
printf("%s source result\n", argv[0]);
exit(1);
}
if ((wz = fopen(argv[1], "r")) == NULL) {
printf("Open error %s\n", argv[1]);
exit(1);
}
if ((wc = fopen(argv[2], "w")) == NULL) {
printf("Open error %s\n", argv[2]);
exit(2);
}
// NOTE/BUG: _pointers_ p and q are _unitialized_
#if 0
readZ(wz, p, q);
#else
readZ(wz, &a1, &b1);
#endif
// NOTE/BUG: a1 and b1 are _unitialized_ -- assume that above readZ needs to
// be changed
double complex z1 = a1 + b1 * I;
writeZ(wc, z1);
printf("%.2f, %.2f\n", creal(z1), cimag(z1));
// NOTE/BUG: _pointers_ r and s are _unitialized_
#if 0
readZ(wz, r, s);
#else
readZ(wz, &a2, &b2);
#endif
// NOTE/BUG: a2 and b2 are _unitialized_ -- assume that above readZ needs to
double complex z2 = a2 + b2 * I;
printf("%.2f, %.2f\n", creal(z2), cimag(z2));
// NOTE/BUG: arguments are backwards if you want csum* to be the _sum_
#if 0
sumZ(p, q, r, s, t, u);
#endif
#if 0
sumZ(a1, b1, a2, b2, &csum1, &csum2);
#endif
#if 1
sumZ(z1, z2, &csum1);
#endif
printf("%.2f, %.2f\n", creal(csum1), cimag(csum1));
fclose(wz);
fclose(wc);
return 0;
}
Here's a cleaned up version that changes readZ
to return a double complex
directly, which is [probably] closer to what was intended:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <math.h>
#include <complex.h>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
void
readZ(FILE *wp, double complex *rtn)
{
char c;
double a;
double b;
assert(fscanf(wp, "%c%lg%c%lg%c%c", &c, &a, &c, &b, &c, &c));
*rtn = a + b * I;
}
int
writeZ(FILE *wp, double complex z)
{
fprintf(wp, "%.2f, %.2f\n", creal(z), cimag(z));
return 1;
}
void
sumZ(double complex a1, double complex b1, double complex *c1)
{
*c1 = a1 + b1;
}
int
main(int argc, char *argv[])
{
FILE *wz;
FILE *wc;
double complex csum1;
if (argc != 3) {
printf("Wrong arguments number\n");
printf("I should run this way:\n");
printf("%s source result\n", argv[0]);
exit(1);
}
if ((wz = fopen(argv[1], "r")) == NULL) {
printf("Open error %s\n", argv[1]);
exit(1);
}
if ((wc = fopen(argv[2], "w")) == NULL) {
printf("Open error %s\n", argv[2]);
exit(2);
}
double complex z1;
readZ(wz, &z1);
writeZ(wc, z1);
printf("%.2f, %.2f\n", creal(z1), cimag(z1));
double complex z2;
readZ(wz, &z2);
printf("%.2f, %.2f\n", creal(z2), cimag(z2));
sumZ(z1, z2, &csum1);
printf("%.2f, %.2f\n", creal(csum1), cimag(csum1));
fclose(wz);
fclose(wc);
return 0;
}