length of an array using sizeof() - problem

F

fdunne2

The following C-code implements a simple FIR filter:

//realtime filter demo

#include <stdio.h>
#include <stdlib.h>

//function defination
float rtFilter1(float *num, float *den, float *xPrev, float *yPrev);

void main()
{
float sig_in[30], numerator[3], denominator[3], x[3], y[2], s_out[30];
int i;
int kk;

//unit impulse
sig_in[0] = 1.0;
printf("unit impulse... \n");
printf("input element number: 1 = %f \n", sig_in[0]);

for(i = 1; i<30; i++)
{
sig_in = 0.0;
printf("input element number: %d = %f\n", i+1, sig_in);
}

//initialise previous input and output arrays
for(i = 0; i<3; i++)
{
x = 0.0;
}

for(i = 0; i<2; i++)
{
y = 0.0;
}


//set filter coefficients

numerator[0] = 1;
numerator[1] = 1.71;
numerator[2] = 0.94;

// test
kk = sizeof(numerator)/sizeof(float);

denominator[0] = 1;
denominator[1] = -1.865;
denominator[2] = 0.889;

printf("\n\noutput signal values...\n");

//print output signal
for(i = 0; i<30; i++)
{
x[0] = sig_in;
s_out = rtFilter1(numerator, denominator, x, y);

printf("output element number: %d = %f\n", i+1, s_out);
}


}


//a(1)*y(n) = b(1)*x(n) + b(2)*x(n-1) + ... + b(nb+1)*x(n-nb) - a(2)*y(n-1) - ... - a(na+1)*y(n-na)

// realtime filter - direct form I - single input(xPrev[0]) / single output(sig_out)
float rtFilter1(float *num, float *den, float *xPrev, float* yPrev)
{
//positive sum
float psum = 0.0;
//negitive sum
float nsum = 0.0;

float sig_out;

//get length of numerator coefficient array
int numLen = sizeof(num)/sizeof(float);
//get length of denominator coefficient array
int denLen = 3;
int i;

//calc. positive sum
for(i = 0; i<numLen; i++)
{
psum = psum + num*xPrev;

}

//calc. negitive sum
for(i = 1; i<denLen; i++) // i=1 in order to bypass first denominator array element, den[0] (=1)
{
nsum = nsum + den*yPrev[i-1];
}

//shift memory

//shift values in previous input array

for(i = 2; i<=numLen; i++) //the last element in xPrev is xPrev[numLen-1], ie length(xPrev) == length(num)
{
xPrev[(numLen-i)+1] = xPrev[numLen-i]; // shifts each array value up a element eg xPrev[1] = xPrev[0]

}

//shift values in previous output array

for(i = 3; i<=denLen; i++) // i=3 because yPrev has 1 less element than denLen
{
yPrev[(denLen-i)+1] = yPrev[denLen-i]; // shifts each aeeay value up a element eg yPrev[1] = yPrev[0]

}

//calc. output signal
yPrev[0] = psum - nsum;
sig_out = yPrev[0];

return sig_out;

} //end rtFilter1

My problem is as follows:

The following code calculates the number of elements in an array(num):

int numLen = sizeof(num)/sizeof(float);

This method of finding array length is used in rtFilter, however it produces the wrong result. It produces the correct result when used in the main function though.

i.e.

// test
kk = sizeof(numerator)/sizeof(float);

Does anyone know why I am getting two different results for basicly the same line of code?

Is there anyway I can find the length of the array(numerator) inside the function rtFilter()?

Note: I've used arrays of 4 elements here just to test the program. Usually the array lengths are unknown.

Thanks.
 
M

Mark A. Odell

void main() /* AGHHH!!! */
int main(void)

[snip]
My problem is as follows:

The following code calculates the number of elements in an array(num):

int numLen = sizeof(num)/sizeof(float);

First, write a macro like this:

#define NUM_OF(a) (sizeof (a) / sizeof *(a))

and use it like:

int numLen = NUM_OF(num);
This method of finding array length is used in rtFilter, however it
produces the wrong result. It produces the correct result when used in
the main function though.

Next, understand that once you "pass" an array to another function as a
parameter it decays in to a pointer to the first element of the array and
the sizeof operator will not work as you wish it to. You need to pass the
sizeof num to the function rtFilter() as an additional parameter.
 
J

Jens.Toerring

fdunne2 said:
The following C-code implements a simple FIR filter:
//realtime filter demo
#include <stdio.h>
#include <stdlib.h>
//function defination
float rtFilter1(float *num, float *den, float *xPrev, float *yPrev);
void main()
{
float sig_in[30], numerator[3], denominator[3], x[3], y[2], s_out[30];
int i;
int kk;

kk = sizeof(numerator)/sizeof(float);

s_out = rtFilter1(numerator, denominator, x, y);

My problem is as follows:
The following code calculates the number of elements in an array(num):
int numLen = sizeof(num)/sizeof(float);
This method of finding array length is used in rtFilter, however it produces
the wrong result. It produces the correct result when used in the main
function though.

That's because in main() you apply sizeof to a real array (numerator) but
in rtFilter1() to just a float pointer. Thus in main() you get the size
of the array while in rtFilter1() you get the size of a float pointer.
Is there anyway I can find the length of the array(numerator) inside the
function rtFilter()?

You have to pass the length of the array together with the pointer to the
array to rtFilter1(). There is no way you can find out the length of the
array the pointer is pointing to just from the pointer itself.

Regards, Jens
 
A

Artie Gold

fdunne2 said:
The following C-code implements a simple FIR filter:

//realtime filter demo

#include <stdio.h>
#include <stdlib.h>

//function defination
float rtFilter1(float *num, float *den, float *xPrev, float *yPrev);

void main() `main' returns `int'!!!!!!!!
{
float sig_in[30], numerator[3], denominator[3], x[3], y[2], s_out[30];
int i;
int kk; [snip]

// test
kk = sizeof(numerator)/sizeof(float);

This is valid, as `numerator' is an array that's in scope.
[snip]
}


//a(1)*y(n) = b(1)*x(n) + b(2)*x(n-1) + ... + b(nb+1)*x(n-nb) - a(2)*y(n-1) - ... - a(na+1)*y(n-na)

// realtime filter - direct form I - single input(xPrev[0]) / single output(sig_out)
float rtFilter1(float *num, float *den, float *xPrev, float* yPrev)
{
//positive sum
float psum = 0.0;
//negitive sum
float nsum = 0.0;

float sig_out;

//get length of numerator coefficient array
int numLen = sizeof(num)/sizeof(float);

In this case `num' an argument has decayed into a pointer to the first
element of the array it has been passed; its size is lost. Hence the
value will always be the size of a pointer-to-float divided by the size
of a float. Not what you want. ;-(

[snip]
} //end rtFilter1

My problem is as follows:

The following code calculates the number of elements in an array(num):

int numLen = sizeof(num)/sizeof(float);

This method of finding array length is used in rtFilter, however it produces the wrong result. It produces the correct result when used in the main function though.

i.e.

// test
kk = sizeof(numerator)/sizeof(float);

Does anyone know why I am getting two different results for basicly the same line of code?

Is there anyway I can find the length of the array(numerator) inside the function rtFilter()?

Note: I've used arrays of 4 elements here just to test the program. Usually the array lengths are unknown.
You can't (directly) pass arrays in C. When you do pass one, you're
really passing a pointer to its first element.

Please see http://www.eskimo.com/~scs/C-faq/s6.html for further
explanations.

HTH,
--ag
 
L

Lew Pitcher

fdunne2 said:
The following C-code implements a simple FIR filter:

//realtime filter demo

#include <stdio.h>
#include <stdlib.h>

//function defination
float rtFilter1(float *num, float *den, float *xPrev, float *yPrev);

void main()

Please correct this. On hosted implementations, main() returns an int.
{
float sig_in[30], numerator[3], denominator[3], x[3], y[2], s_out[30];
int i;
int kk;

//unit impulse
sig_in[0] = 1.0;
printf("unit impulse... \n");
printf("input element number: 1 = %f \n", sig_in[0]);

for(i = 1; i<30; i++)
{
sig_in = 0.0;
printf("input element number: %d = %f\n", i+1, sig_in);
}

//initialise previous input and output arrays
for(i = 0; i<3; i++)
{
x = 0.0;
}

for(i = 0; i<2; i++)
{
y = 0.0;
}


//set filter coefficients

numerator[0] = 1;
numerator[1] = 1.71;
numerator[2] = 0.94;

// test
kk = sizeof(numerator)/sizeof(float);

denominator[0] = 1;
denominator[1] = -1.865;
denominator[2] = 0.889;

printf("\n\noutput signal values...\n");

//print output signal
for(i = 0; i<30; i++)
{
x[0] = sig_in;
s_out = rtFilter1(numerator, denominator, x, y);

printf("output element number: %d = %f\n", i+1, s_out);
}


Unless you are compiling with a C99-compliant compiler, you are obliged to
return an int value here. Please do so.
}


//a(1)*y(n) = b(1)*x(n) + b(2)*x(n-1) + ... + b(nb+1)*x(n-nb) - a(2)*y(n-1) - ... - a(na+1)*y(n-na)

// realtime filter - direct form I - single input(xPrev[0]) / single output(sig_out)
float rtFilter1(float *num, float *den, float *xPrev, float* yPrev)
{
//positive sum
float psum = 0.0;
//negitive sum
float nsum = 0.0;

float sig_out;

//get length of numerator coefficient array
int numLen = sizeof(num)/sizeof(float);
//get length of denominator coefficient array
int denLen = 3;
int i;

//calc. positive sum
for(i = 0; i<numLen; i++)
{
psum = psum + num*xPrev;

}

//calc. negitive sum
for(i = 1; i<denLen; i++) // i=1 in order to bypass first denominator array element, den[0] (=1)
{
nsum = nsum + den*yPrev[i-1];
}

//shift memory

//shift values in previous input array

for(i = 2; i<=numLen; i++) //the last element in xPrev is xPrev[numLen-1], ie length(xPrev) == length(num)
{
xPrev[(numLen-i)+1] = xPrev[numLen-i]; // shifts each array value up a element eg xPrev[1] = xPrev[0]

}

//shift values in previous output array

for(i = 3; i<=denLen; i++) // i=3 because yPrev has 1 less element than denLen
{
yPrev[(denLen-i)+1] = yPrev[denLen-i]; // shifts each aeeay value up a element eg yPrev[1] = yPrev[0]

}

//calc. output signal
yPrev[0] = psum - nsum;
sig_out = yPrev[0];

return sig_out;

} //end rtFilter1

My problem is as follows:

The following code calculates the number of elements in an array(num):

int numLen = sizeof(num)/sizeof(float);

This method of finding array length is used in rtFilter, however it produces the wrong result. It produces the correct result when used in the main function though.

i.e.

// test
kk = sizeof(numerator)/sizeof(float);

Does anyone know why I am getting two different results for basicly the same line of code?


Yes.

In rtFilter1(), you've declared num to be a pointer (a pointer to float, to
be exact). You /have not/ declared num to be an array of some number of
float values. Thus, in rtFilter1(), when you perform the computation
int numLen = sizeof(num)/sizeof(float);
you are computing the relative proportions of a float as compared to a
pointer. You /are not/ computing the number of float elements in the array
that num (possibly) represents


However, in main(), you've declared numerator as an array of three float
values. Thus, when you perform the computation
kk = sizeof(numerator)/sizeof(float);
you are computing the relative proportions of a single float to an array of
floats, and thus deriving the number of float values that the array can hold.
 
A

Arthur J. O'Dwyer

The following C-code implements a simple FIR filter:

Your question has been answered crossthread.
I've taken the liberty of refactoring your code somewhat.
Snipped yours, added mine below. Note particularly the
replacement of 'float' by 'double' ('float' is too fuzzy for
most calculations, unless you are really strapped for RAM);
the C-style comments; 'int main'; and the reversed indexing
in the for loops. UNTESTED CODE.


/* realtime filter demo */

#include <stdio.h>
#include <stdlib.h>

#define ELTS(x) (sizeof (x) / sizeof *(x))

double rtFilter1(double *num, size_t nlen, double *den, size_t dlen,
double *xPrev, double *yPrev);

int main(void)
{
double sig_in[30] = {1.0, /* zeroes */ };
double x[3] = {0., 0., 0.};
double y[2] = {0., 0.};
double numerator[3];
double denominator[3];
double s_out[30];
int i;

printf("unit impulse... \n");
for (i=0; i < 30; ++i)
{
printf("input element number: %d = %f\n", i+1, sig_in);
}

/* set filter coefficients */
numerator[0] = 1;
numerator[1] = 1.71;
numerator[2] = 0.94;

denominator[0] = 1;
denominator[1] = -1.865;
denominator[2] = 0.889;

printf("\n\noutput signal values...\n");
for (i=0; i < 30; ++i)
{
x[0] = sig_in;
s_out = rtFilter1(numerator, ELTS(numerator),
denominator, ELTS(denominator), x, y);

printf("output element number: %d = %f\n", i+1, s_out);
}

return 0;
}


/* a(1)*y(n) = b(1)*x(n) + b(2)*x(n-1) + ... + b(nb+1)*x(n-nb)
* - a(2)*y(n-1) - ... - a(na+1)*y(n-na)
*
* realtime filter
* - direct form I
* - single input(xPrev[0]) / single output(sig_out)
*
* We require that xPrev be as long as num, and yPrev be one less
* than the length of den. It is assumed that den[0]==1.
*/
double rtFilter1(double *num, size_t nlen,
double *den, size_t dlen,
double *xPrev, double *yPrev)
{
double psum = 0.0; /* positive sum */
double nsum = 0.0; /* negative sum */
size_t i;

for (i=0; i < nlen; ++i)
psum += num * xPrev;

/* bypass first denominator array element, den[0] (=1) */
for (i=1; i < dlen; ++i)
nsum += den * yPrev[i-1];

/* shift values in previous input and output arrays */

for (i = nlen-1; i >= 1; --i)
xPrev = xPrev[i-1];

for (i = dlen-2; i >= 1; --i)
yPrev = yPrev[i-1];

/* return a result */

yPrev[0] = psum - nsum;
return yPrev[0];
}
 
D

donLouis

printf("output element number: %d = %f\n", i+1, s_out);
}


Unless you are compiling with a C99-compliant compiler, you are obliged to
return an int value here. Please do so.


Although I wouldn't omit the return, it isn't required.
 
D

donLouis

printf("output element number: %d = %f\n", i+1, s_out);
}


Unless you are compiling with a C99-compliant compiler, you are obliged to
return an int value here. Please do so.


Although I wouldn't omit the return, it isn't required.


In fact, as Lew said, it is, unless you have a C99 compiler.


If I understand this correctly, by omitting the return on a C89
program, the exit status of the program is undefined, but the
program itself is fine. I _believe_ that the following two programs
are correct.

#include <stdio.h>

int main(void) {
printf("whatever\n");
}

int main(void) {
while(1)
;
}

On the first one, my system issues a warning, the exit status becomes
unusable, and I'm _not_ stating that you should omit the return,
only that it is not required by C89. On the second one, not only do
I get a clean compile, but the absence of a return is intentional.

If I understood them correctly, Dan Pop and Barry Schwarz clarified
this for me about a year ago.
 
L

Lew Pitcher

donLouis said:
printf("output element number: %d = %f\n", i+1, s_out);
}


Unless you are compiling with a C99-compliant compiler, you are obliged to
return an int value here. Please do so.



Although I wouldn't omit the return, it isn't required.


How is what I said any different from what you said?

If the OP isn't using C99, then he is obliged to return an int value at the end
of the main() function. He can do so through a return statement, or an exit()
function, but he /must/ return an int on a hosted implementation.

However, with C99, the main() function can terminate without returning an int
value (either through a return statement or through an exit() function). In this
case, a C99 hosted implementation will supply a return value for the main()
function.




--
Lew Pitcher

Master Codewright and JOAT-in-training
Registered Linux User #112576 (http://counter.li.org/)
Slackware - Because I know what I'm doing.
 
P

Peter Nilsson

....
If the OP isn't using C99, then he is obliged to return an int value
at the end of the main() function. He can do so through a return
statement, or an exit() function, but he /must/ return an int on a
hosted implementation.

Falling off main _will_ return an int value, albeit an unspecified one. It's
certainly courtesy to explicitly return a value, if only to cater for shell
scripts (or the like) which may capriciously stop, if an inappropriate exit
code is received.

Falling off _any_ non-void function remains valid even in C99. UB is only
invoked if the calling function attempts to use the return value.
 
D

donLouis

donLouis said:
printf("output element number: %d = %f\n", i+1, s_out);
}


Unless you are compiling with a C99-compliant compiler, you are obliged to
return an int value here. Please do so.



Although I wouldn't omit the return, it isn't required.


How is what I said any different from what you said?

If the OP isn't using C99, then he is obliged to return an int value at the
end
of the main() function. He can do so through a return statement, or an exit()
function, but he /must/ return an int on a hosted implementation.


It's the _obliged_ and _must_ part that I disagree with. In most
programs, the OP's included, C99 or otherwise, that you _should_
explicitly return from main.
However, with C99, the main() function can terminate without returning an int
value (either through a return statement or through an exit() function). In
this
case, a C99 hosted implementation will supply a return value for the main()
function.

I still wouldn't omit the return "just because it's C99", but that's
probably force of habit on my part.

I do, however, omit the return in cases where main isn't supposed to
be exiting at all, or, although uncommon, when it is understood that
the return value is useless.

/* OT certain GUI stuff as well OT */
 
F

fdunne2

Thanks for helping me out!

Just another quick question:

I'm unfamiliar with the following statement:

#define ELTS(x) (sizeof (x) / sizeof *(x))

Can you explain to me what the function of this is in the context of the entire program?

I kinda get it. My main concern where the type 'size_t' (inside the rtFilter() definition) came from.

Regards,
F.
 
P

pete

fdunne2 said:
Thanks for helping me out!

Just another quick question:

I'm unfamiliar with the following statement:

#define ELTS(x) (sizeof (x) / sizeof *(x))

Can you explain to me what the function of
this is in the context of the entire program?

When x is the name of an array,
then ELTS(x) equals the number of elements in the array.
When x is a just pointer,
then ELTS(x) is not meaningful in any general way.
 
R

Richard Bos

donLouis said:
On Fri, 23 Jan 2004 09:47:20 -0500

printf("output element number: %d = %f\n", i+1, s_out);
}


Unless you are compiling with a C99-compliant compiler, you are obliged to
return an int value here. Please do so.

Although I wouldn't omit the return, it isn't required.


In fact, as Lew said, it is, unless you have a C99 compiler.


If I understand this correctly, by omitting the return on a C89
program, the exit status of the program is undefined, but the
program itself is fine.


Nope. Returning anything except 0, EXIT_SUCCESS or EXIT FAILURE makes
the program defined, but its exit status undefined. _Not_ returning
anything at all makes the program undefined; it could, for example,
confuse the startup code into crashing, much as declaring main() to
return a float could.
I _believe_ that the following two programs
are correct.

#include <stdio.h>

int main(void) {
printf("whatever\n");
}

This is not...
int main(void) {
while(1)
;
}

....but this never returns at all, let alone a possibly bogus value to
the startup code, so it is correct.

Richard
 
P

Peter Nilsson

Richard Bos said:
donLouis said:
47:20 -0500

printf("output element number: %d = %f\n", i+1, s_out);
}


Unless you are compiling with a C99-compliant compiler, you are obliged to
return an int value here. Please do so.

Although I wouldn't omit the return, it isn't required.

In fact, as Lew said, it is, unless you have a C99 compiler.


If I understand this correctly, by omitting the return on a C89
program, the exit status of the program is undefined, but the
program itself is fine.


Nope. Returning anything except 0, EXIT_SUCCESS or EXIT FAILURE makes
the program defined, but its exit status undefined. _Not_ returning
anything at all makes the program undefined;


Chapter and verse, please.

AFAIK, the C90 language specification says _nothing_ about what the host
does with an exit status, defined or otherwise.
it could, for example,
confuse the startup code into crashing, much as declaring main() to
return a float could.

My draft C89 copy says...

2.1.2.2 Hosted environment
...
"Program termination"

A return from the initial call to the main function is equivalent
to calling the exit function with the value returned by the main
function as its argument. If the main function executes a return that
specifies no value, the termination status returned to the host
environment is undefined.

3.6.6.4 The return statement
...
If a return statement without an expression is executed, and the
value of the function call is used by the caller, the behavior is
undefined. Reaching the } that terminates a function is equivalent to
executing a return statement without an expression.


If the first sentence of "Program termination" were the only clause, then
you would have a case because of 3.6.6.4, but it _explicitly_ goes on to
state that a termination status _is_ returned to the host, albeit an
undefined one.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,905
Latest member
Kristy_Poole

Latest Threads

Top