## C coding problem

Moderators: phlip, Moderators General, Prelates

Yuhzaan Vong
Posts: 13
Joined: Thu Feb 24, 2011 12:39 am UTC

### C coding problem

I'm kind of new at this, and I have this program I'm trying to get to work.
--------------------
#include <stdio.h>
#include <math.h>

void moment (float data[], int n, float *ave, float *adev, float *sdev, float *var, float *skew, float *curt)
//Given an array of data[1..n], this routine returns its mean ave, average deviation adev, standard deviation sdev, variance var, skewness skew, and kurtosis curt.
{
void nrerror(char error_text[]);
int j;
float ep=0.0,s,p;

if (n <= 1 ) nrerror("n must be at least 2 in moment");
s=0.0;
for (j=1;j<=n;j++) s += data[j];
*ave=s/n;
*adev=(*var)=(*skew)=(*curt)=0.0; //Second pass to get the first (absolute), second, third, and fourth moments of the deviation from the mean.
for (j=1;j<=n;j++) {
*var += (p=s*s);
*skew += (p *= s);
*curt += (p *= s);
}
*var=(*var-ep*ep/n)/(n-1); //Corrected two-pass formula.
*sdev=sqrt(*var); //Put the pieces together according to the conventional definitions.
if (*var) {
*skew /= (n*(var)*(*sdev)); // HERE
*curt=(*curt)/(n*(*var)*(*var))-3.0;
} else nrerror("No skew/kurtosis when variance = 0 (in moment))");
}
-----------------
I try to compile it, and it says that there is an error at line 26. This line (also marked up on the program with a "here")

*skew /= (n*(var)*(*sdev));

it says that operands of * have illegal types 'int' and 'pointer to float'.
I don't really understand pointers, so I have no idea how to fix this.
Please know that I didn't write this program; I am simply trying to get it to work.

phlip
Restorer of Worlds
Posts: 7572
Joined: Sat Sep 23, 2006 3:56 am UTC
Location: Australia
Contact:

### Re: C coding problem

n is an int, but var is a pointer to a float, so you can't multiply them. Did you mean "*var" instead of "var" in that line?

Code: Select all

`enum ಠ_ಠ {°□°╰=1, °Д°╰, ಠ益ಠ╰};void ┻━┻︵​╰(ಠ_ಠ ⚠) {exit((int)⚠);}`
[he/him/his]

Yuhzaan Vong
Posts: 13
Joined: Thu Feb 24, 2011 12:39 am UTC

### Re: C coding problem

Yes. thank you.
If I may ask one more question:
I had to revise the code a bit (the rest of the program wasn't working right).
When I run it, it displays this error:

Exception 0xc0000005:
Segment violation

Then it just says abnormal program termination.

Here is the revised code:
-------------
#include <stdio.h>
#include <math.h>

void main (float data[], int n, float *ave, float *adev, float *sdev, float *var, float *skew, float *curt)
//Given an array of data[1..n], this routine returns its mean ave, average deviation adev,
//standard deviation sdev, variance var, skewness skew, and kurtosis curt.
{
//void nrerror(char error_text[]);
int j;
float ep=0.0,s,p;

if (n <= 1 ) printf("n must be at least 2 in the moment");
s=0.0;
for (j=1;j<=n;j++) s += data[j];
*ave=s/n;
*adev=(*var)=(*skew)=(*curt)=0.0; //Second pass to get the first (absolute), second, third, and fourth moments of the deviation from the mean.
for (j=1;j<=n;j++) {
*var += (p=s*s);
*skew += (p *= s);
*curt += (p *= s);
}
*var=(*var-ep*ep/n)/(n-1); //Corrected two-pass formula.
*sdev=sqrt(*var); //Put the pieces together acccording to the conventional definitions.
if (*var) {
*skew /= (n*(*var)*(*sdev));
*curt=(*curt)/(n*(*var)*(*var))-3.0;
} else printf("No skew/kurtosis when variance = 0 (in moment))");

}
-------------

I just changed the var to *var, and changed the references to nrerror to just printf statements.

phlip
Restorer of Worlds
Posts: 7572
Joined: Sat Sep 23, 2006 3:56 am UTC
Location: Australia
Contact:

### Re: C coding problem

Yuhzaan Vong wrote:void main (float data[], int n, float *ave, float *adev, float *sdev, float *var, float *skew, float *curt)

This is going to cause many problems. "main" can either be defined with no parameters as "int main(void)", or two parameters as "int main(int argn, char **argv)" to get the command-line arguments to the program. If you define it any other way, the parameters when you run it will be gibberish, because that's not how the function is called.

So all the pointers there are going to be gibberish - which means they'll point to random places in memory. Chances are, they'll be places in memory that aren't actually part of your program... so your program doesn't have access to read them. So when you try to read from them, your program crashes with an "Access Violation" error (that's the 0xC0000005 error code you have). The same error is also called a "segfault", since that is the error message on *nix.

You'll have to rename the function to something else (eg "moment", what it was called in your original post) and then have main() call it with the appropriate parameters, and do appropriate thing with the results. Also, you should compile with warnings turned on - the compiler should have warned you that your definition of "main" wasn't kosher.

As an aside, you should post your code in "code" blocks, like [code]this[/code], which looks like:

Code: Select all

`this`
That way, all your indenting is preserved.

Code: Select all

`enum ಠ_ಠ {°□°╰=1, °Д°╰, ಠ益ಠ╰};void ┻━┻︵​╰(ಠ_ಠ ⚠) {exit((int)⚠);}`
[he/him/his]

Yuhzaan Vong
Posts: 13
Joined: Thu Feb 24, 2011 12:39 am UTC

### Re: C coding problem

Ok, thanks. How would I go about calling on moment? Would I just say "goto moment"?
Also, warnings were on. I guess it just didn't catch it :/

_Axle_
Posts: 253
Joined: Fri Sep 24, 2010 7:33 pm UTC

### Re: C coding problem

In addition to what phlip has mentioned..

When writing a function where you are expecting pointers, its best to test if they are 'valid' before de-referencing them.
Example :

Code: Select all

`int foo(int a, int* b){  if(b)  {     *b = a * 5;  }   return a * 5;}`
Yakk wrote:Computer Science is to Programming as Materials Physics is to Structural Engineering.

archeleus
Posts: 240
Joined: Wed Sep 29, 2010 1:49 pm UTC
Location: Valenvaryon
Contact:

### Re: C coding problem

Yuhzaan Vong wrote:Ok, thanks. How would I go about calling on moment? Would I just say "goto moment"?
Also, warnings were on. I guess it just didn't catch it :/

Code: Select all

`void foo(float arg){     /*      * Do whatever here      */     }float bar(){ /* no arguments */      /* stuff */      return something;      }int main(int argc, char **argv){    /* stuff */    foo(arg); /* this is a function call */        float value = bar(); /* likewise, but catching return */        return 0;       }`

Also, as a programmer you should never ignore warnings because they can very well turn out to be syntax errors/other errors on another system/dataset.
I write a blog rant here.

Yuhzaan Vong
Posts: 13
Joined: Thu Feb 24, 2011 12:39 am UTC

### Re: C coding problem

Ok. I modified the code, but it doesn't return anything. it works, but nothing happens. I tried putting in arguments in, but all it returns is the file directory the program is in, and the arguments right after them. For example, if I put in arguments 1 2 3 4 5, it comes back with: c\lcc\hello.c 1 2 3 4 5

Code: Select all

`#include <stdio.h>#include <math.h>void main(){   void moment(float data[], int n, float *ave, float *adev, float *sdev, float *var, float *skew, float *curt);}void moment (float data[], int n, float *ave, float *adev, float *sdev, float *var, float *skew, float *curt)//Given an array of data[1..n], this routine returns its mean ave, average deviation adev,//standard deviation sdev, variance var, skewness skew, and kurtosis curt.{    //void nrerror(char error_text[]);    int j;    float ep=0.0,s,p;    if (n <= 1 ) printf("n must be at least 2 in the moment");    s=0.0;    for (j=1;j<=n;j++) s += data[j];    *ave=s/n;    *adev=(*var)=(*skew)=(*curt)=0.0;     //Second pass to get the first (absolute), second, third, and fourth moments of the deviation from the mean.    for (j=1;j<=n;j++) {        *adev += /*fabs*/(s=data[j]-(*ave));        *var += (p=s*s);        *skew += (p *= s);        *curt += (p *= s);    }    //*adev /+ n;    *var=(*var-ep*ep/n)/(n-1);   //Corrected two-pass formula.    *sdev=sqrt(*var);    //Put the pieces together acccording to the conventional definitions.    if (*var) {        *skew /= (n*(*var)*(*sdev));        *curt=(*curt)/(n*(*var)*(*var))-3.0;    } else printf("No skew/kurtosis when variance = 0 (in moment))");}`

hotaru
Posts: 1045
Joined: Fri Apr 13, 2007 6:54 pm UTC

### Re: C coding problem

Code: Select all

`factorial = product . enumFromTo 1isPrime n = factorial (n - 1) `mod` n == n - 1`

archeleus
Posts: 240
Joined: Wed Sep 29, 2010 1:49 pm UTC
Location: Valenvaryon
Contact:

### Re: C coding problem

Who has the time to read that document?

Anyway OP, how are you passing in your arguments and how are you displaying the results?
I write a blog rant here.

Robert'); DROP TABLE *;
Posts: 730
Joined: Mon Sep 08, 2008 6:46 pm UTC
Location: in ur fieldz

### Re: C coding problem

The code you posted shouldn't do anything at all, because main doesn't actually have any instructions. What you've got,

Code: Select all

`void moment(float data[], int n, float *ave, float *adev, float *sdev, float *var, float *skew, float *curt);`

which tells the compiler, "There's a function called moment, which returns nothing and takes arguments..."
However, that's not what you want. You want the compiler to run the function, and the syntax for that is simply...

Code: Select all

`int main(int argn, char **argv) {       // Sidenote: If we declared main(void), we couldn't get to the arguments you're actually telling the program.      moment(a, b, c, d, e, f, g, h);}`

(where a is something of type float[], b is an integer, and the rest are pointers to floats)
...And that is how we know the Earth to be banana-shaped.

Killamus
Posts: 163
Joined: Sun Jan 24, 2010 3:26 am UTC

### Re: C coding problem

On a slightly related note; your function does far too much. A typical function should do one thing, and do it well. What if you just wanted the stddev of a set of numbers? Or just the mean? Yes, in theory, you can either (A) make a bunch of facades and work through that, or you would have to pass it variables that you'd never use. It would waste computational time. Maybe not that much, but there's the idea of the Zero, One Infinity rule which states that you can either have one of something, none of something, or infinite of something. So, if you had an infinite amount of lists of numbers that you needed to get just the mean of, you're also doing the rest of the calculations as well, causing the work to take 5x as long.

Plus, it just makes the code look bad.

Now, that being said, no one here has stated how to use command line arguments in a C/C++ application.

Code: Select all

`int main(int argc, char** args)`

is a common way to define the main header, the other

Code: Select all

`int main()`
doesn't take arguments, so we're going to ignore it.
So, let's start defining:
argc: An integer stating the number of arguments that were passed. This number will always be greater then one, unless it overflows.
args: A list of a list of characters. This is the actual arguments that were passed.
args[i]: A list of characters that consists of how the function was called. So, if I have a program called a.out, and I called it by typing in a command prompt: "./a.out Hello, My name is Killamus", my arguments would be as follows:
[0] ./a.out
[1] Hello,
[2] My
[3] name
[4] is
[5] Killamus

Take note that there isn't any spaces in those lines. Now, if I called it by typing into a command prompt: "/home/Killamus/a.out Hello World!", I would have the following arguments:
[0] /home/Killamus/a.out
[1] Hello
[2] World!

If you want to play around with them for a bit, this is a program I wrote up real quick to verify that I remembered correctly:

Code: Select all

`#include <stdio.h>#include <stdlib.h>int main(int argc, char** args){        printf("I was called by: %s\n", args[0]);        for (int i = 1; i < argc; i++)        {                printf("%s\n", args[i]);        }}`

Thus, for your program to work, you would want to declare an array of floats, then iterate from 1-argc of your arguments, converting each one to a float as you go through, then call your function, then output the values in the pointers that you're passing back.

hotaru
Posts: 1045
Joined: Fri Apr 13, 2007 6:54 pm UTC

### Re: C coding problem

archeleus wrote:Who has the time to read that document?

anyone who wants to accomplish anything that has anything at all to do with c.

Code: Select all

`factorial = product . enumFromTo 1isPrime n = factorial (n - 1) `mod` n == n - 1`

archeleus
Posts: 240
Joined: Wed Sep 29, 2010 1:49 pm UTC
Location: Valenvaryon
Contact:

### Re: C coding problem

So not the op.
I write a blog rant here.

Yuhzaan Vong
Posts: 13
Joined: Thu Feb 24, 2011 12:39 am UTC

### Re: C coding problem

Thanks guys. I got the program working, and I'm figuring out how to read a set of data into it so it can find the mean, average, etc. You have been a great help