C coding problem

"Please leave a message at the beep, we will get back to you when your support contract expires."

Moderators: phlip, Moderators General, Prelates

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

C coding problem

Postby Yuhzaan Vong » Thu Feb 24, 2011 1:32 am UTC

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++) {
*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 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.

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

Re: C coding problem

Postby phlip » Thu Feb 24, 2011 1:34 am UTC

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

Postby Yuhzaan Vong » Thu Feb 24, 2011 2:01 am UTC

Yes. :D 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
Address: 0x401317

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++) {
*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))");


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

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

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

Re: C coding problem

Postby phlip » Thu Feb 24, 2011 2:17 am UTC

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

Postby Yuhzaan Vong » Thu Feb 24, 2011 2:25 am UTC

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

Postby _Axle_ » Thu Feb 24, 2011 2:27 am UTC

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

Postby archeleus » Fri Feb 25, 2011 1:50 pm UTC

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

Postby Yuhzaan Vong » Sat Feb 26, 2011 12:51 am UTC

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))");


}

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

Re: C coding problem

Postby hotaru » Sat Feb 26, 2011 2:35 am UTC

please read this.

Code: Select all

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

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

Re: C coding problem

Postby archeleus » Sat Feb 26, 2011 10:49 am UTC

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.

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

Re: C coding problem

Postby Robert'); DROP TABLE *; » Sat Feb 26, 2011 9:00 pm UTC

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

Postby Killamus » Sun Feb 27, 2011 1:23 am UTC

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.

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

Re: C coding problem

Postby hotaru » Sun Feb 27, 2011 5:49 am UTC

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 1
isPrime n 
factorial (1) `mod== 1

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

Re: C coding problem

Postby archeleus » Sun Feb 27, 2011 2:57 pm UTC

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

Postby Yuhzaan Vong » Tue Mar 01, 2011 2:02 am UTC

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 :)


Return to “The Help Desk”

Who is online

Users browsing this forum: No registered users and 5 guests