By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
429,373 Members | 1,792 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 429,373 IT Pros & Developers. It's quick & easy.

First Program

P: n/a
mwt
Hello. Today I wrote my first program in C. It adds up the elements in
an array. I am just beginning to learn this language. Any tips or
pointers about better ways to write/structure/format/etc. this code
would be much appreciated. Thanks.
mwt.

#include <stdio.h>

int add_array(int arr[], int arr_size)
{
int j;
int total = 0;
for(j = 0; j < arr_size; j++)
total += arr[j];
return(total);

}

main()
{
int size;

printf("Input size of array>");
scanf("%d", &size);
int array[size];
int i;
for(i=0; i<size; i++)
{
array[i] = i+1;

}

printf("Sum of array elements is %d.\n", add_array(array,
size));
}

Apr 13 '06 #1
Share this Question
Share on Google+
26 Replies


P: n/a
"mwt" writes:
Hello. Today I wrote my first program in C. It adds up the elements in
an array. I am just beginning to learn this language. Any tips or
pointers about better ways to write/structure/format/etc. this code
would be much appreciated. Thanks.
mwt.

#include <stdio.h>

int add_array(int arr[], int arr_size)
{
int j;
int total = 0;
for(j = 0; j < arr_size; j++)
total += arr[j];
return(total);

}

main()
{
int size;

printf("Input size of array>");
scanf("%d", &size);
int array[size];
int i;
for(i=0; i<size; i++)
{
array[i] = i+1;

}

printf("Sum of array elements is %d.\n", add_array(array,
size));
}


Assuming that it works, I would say you are off to a good start.
Apr 13 '06 #2

P: n/a
"mwt" <mi*********@gmail.com> writes:
Hello. Today I wrote my first program in C. It adds up the elements in
an array. I am just beginning to learn this language. Any tips or
pointers about better ways to write/structure/format/etc. this code
would be much appreciated. Thanks.

#include <stdio.h>

int add_array(int arr[], int arr_size)
{
int j;
int total = 0;
for(j = 0; j < arr_size; j++)
total += arr[j];
return(total);

}

main()
{
int size;

printf("Input size of array>");
scanf("%d", &size);
int array[size];
^--- looks like a gcc feature so it might not be portable
(is this in C99?).

you should use:

int *array = malloc(size*sizeof(*array))
int i;
for(i=0; i<size; i++)
{
array[i] = i+1;
}

printf("Sum of array elements is %d.\n", add_array(array,
size));
and don't forget to free it when you're finished with it:

free(array)
}


Other than that it looks good. Style is fine AFAICT.

--
burton samograd kruhft .at. gmail
kruhft.blogspot.com www.myspace.com/kruhft metashell.blogspot.com
Apr 13 '06 #3

P: n/a
mwt
>^--- looks like a gcc feature so it might not be portable
(is this in C99?).

I am compiling with gcc. Other than that, I have no idea what type of C
it is.
For learning maximally portable features, what linux-based compiler (or
perhaps flags on gcc) should I be using?

Apr 13 '06 #4

P: n/a
mwt
Ah. I see. If I use the -pendantic option in gcc, it enforces strict
compliance with ISO C90, and won't allow the

int array[size];

declaration.
Interesting.

Apr 13 '06 #5

P: n/a
osmium wrote:
"mwt" writes:
main()
{
int size;

printf("Input size of array>");
scanf("%d", &size);
int array[size];

Assuming that it works, I would say you are off to a good start.


You're pretty easy. What version of C allows both implicit declaration
of functions AND variable-length arrays?


Brian
Apr 13 '06 #6

P: n/a
"mwt" <mi*********@gmail.com> wrote:
Hello. Today I wrote my first program in C. It adds up the elements in
an array. I am just beginning to learn this language. Any tips or
pointers about better ways to write/structure/format/etc. this code
would be much appreciated. Thanks.
mwt.
Compiling (under Linux) with "gcc -Wall -ansi -pedantic first.c"
produces a few warnings. I inserted them at the matching line.

#include <stdio.h>

int add_array(int arr[], int arr_size)
{
int j;
int total = 0;
for(j = 0; j < arr_size; j++)
total += arr[j];
return(total); ( The parenthesis are not necessary. I tend to use them here myself)
}

main() first.c:14: warning: return type defaults to `int'
(Should be "int main(void)" if you do not process command line
parameters) {
int size;

printf("Input size of array>");
scanf("%d", &size);
int array[size]; first.c:19: warning: ISO C89 forbids variable-size array `array'
first.c:19: warning: ISO C89 forbids mixed declarations and code
(Probably too early for you to bother about different versions of C,
but be aware that the language has changed over time) int i;
for(i=0; i<size; i++)
{
array[i] = i+1;

}

printf("Sum of array elements is %d.\n", add_array(array,
size)); first.c:29: warning: control reaches end of non-void function
( missing return EXIT_SUCCESS; - defined in stdlib.h } }


A few comments on style: be consistent. You use braces around the
single statement in the for() loop in the main function, (which is
good,) but not in a similar loop in add_array().

Likewise, you use a "double level" indentation for the function
blocks, but not for the for() loops. Pick a style and stick with it.

A few comments describing the program's purpose would be helpful. They
become much more important for more complex programs.

All in all, very good for a first program!
Apr 13 '06 #7

P: n/a
mwt wrote:
Hello. Today I wrote my first program in C. It adds up the elements in
an array. I am just beginning to learn this language. Any tips or
pointers about better ways to write/structure/format/etc. this code
would be much appreciated. Thanks.
mwt.

#include <stdio.h>

int add_array(int arr[], int arr_size)
{
int j;
int total = 0;
for(j = 0; j < arr_size; j++)
total += arr[j];
return(total);
The parentheses around total are necessary. While not harmful, it
implies that you believe return to be function.
}

main()
This should be declared as:

int main(void)
{
int size;

printf("Input size of array>");
scanf("%d", &size);
You have no way of know whether the person entered a legal value for
size here. Hint, scanf() returns a value, find out why and what it
means. You should also use an unsigned type for size, as you don't want
people entering a negative number. At the very least, you need to check
the number to make sure it's greater than 0.
int array[size];
int i;
for(i=0; i<size; i++)
{
array[i] = i+1;

}

printf("Sum of array elements is %d.\n", add_array(array,
size));
}


The things used above (variable length arrays and declaration of
objects following code) are C99 features. That's not to say that you
shouldn't learn them, just be aware that you won't find them in some
textbooks, notably K&R.

If you are going to use C99, I would recommend moving the declaration
of i into the for loop:

for (int i=0; i<size; i++)
While it is ok to leave out a return from main() in C99, I prefer to
see an explicit one anyway. Purely stylistic.


Brian
Apr 13 '06 #8

P: n/a
"mwt" <mi*********@gmail.com> writes:
Hello. Today I wrote my first program in C. It adds up the elements in
an array. I am just beginning to learn this language. Any tips or
pointers about better ways to write/structure/format/etc. this code
would be much appreciated. Thanks.
mwt.
If this is your first C program, it's an excellent start. I'll offer
a few minor suggestions.
#include <stdio.h>

int add_array(int arr[], int arr_size)
Keep in mind that, in a parameter declaration "int arr[]" is exactly
equivalent to "int *arr"; in other words, you're really passing a
pointer, not an array. Section 6 of the comp.lang.c FAQ,
<http://www.c-faq.com/>, covers arrays and pointers very well.

Some programmers (myself included) prefer not to use this
looks-like-an-array-but-acts-like-a-pointer declaration, but that's
just a matter of style; feel free to use whatever you're comfortable
with.

{
int j;
int total = 0;
for(j = 0; j < arr_size; j++)
total += arr[j];
return(total);
The parentheses are unnecessary. Again, this is a matter of style,
but I prefer "return total;"; a return statement isn't a function
call, and it shouldn't look like one.
}

main()
This should be "int main(void)".
{
int size;
Consider calling this "length" rather than "size". The word "size"
implies sizeof, which gives the size of an object in bytes; the number
of elements in an array is its length. (If sizeof(int)==4, a
10-element array of int has a length of 10 and a size of 40.)
printf("Input size of array>");
Due to buffering, it's not guaranteed that this will appear
immediately. Add "fflush(stdout);" to ensure that the prompt appears
before the program starts waiting for input.
scanf("%d", &size);
You'll find that the scanf() function has some pitfalls. In this
case, it will skip all leading whitespace, including newlines. If you
enter a valid integer, it will leave any characters *following* that
to be read by further calls; for example, if you type "123<ENTER>",
then read a single character, the character you read will be the
new-line character.

It doesn't matter in a small program like this, but it will matter
later on. One good approach is to use fgets() (*never* use gets()) to
read a full line, then use sscanf() to parse it.

Also, scanf() returns a result, which you're ignoring. What happens
if you enter something other than a valid number?
int array[size];
There are two C standards, C90 and C99. C99 theoretically supersedes
C90, but it's not yet universally implemented. For maximum
portability, you should consider sticking to C90 features.

Here you're using two C99-specific features (or perhaps gcc
extensions). C90 doesn't allow declarations to follow statements
within a block, though you can work around it by introducing a new
block. Also, C90 requires array lengths to be compile-time constants;
C99 introduces variable-length arrays, and gcc has supported something
very similar as an extension for some time. Burton Samograd already
suggested using malloc() instead (which also has the advantage that
you can catch allocation errors).
int i;
for(i=0; i<size; i++)
{
array[i] = i+1;

}

printf("Sum of array elements is %d.\n", add_array(array,
size));
You should add "return 0;" here. (It's not strictly required in C99,
but it's a good idea anyway.
}


<OT>

To get warnings about non-standard code (i.e., to persuade gcc to act
as a conforming C compiler), you can use:
gcc -ansi -pedantic -Wall -Wextra
or, for C99:
gcc -std=c99 -pedantic -Wall -Wextra
(but see <http://gcc.gnu.org/c99status.html>).

The "-Wextra" option, equivalent to "-W", may give you more warnings
that are really appropriate.

</OT>

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Apr 13 '06 #9

P: n/a
"mwt" <mi*********@gmail.com> writes:
Ah. I see. If I use the -pendantic option in gcc, it enforces strict
compliance with ISO C90, and won't allow the

int array[size];

declaration.
Interesting.


Please read <http://cfaj.freeshell.org/google/>.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Apr 13 '06 #10

P: n/a
mwt

Keith Thompson wrote:

Please read <http://cfaj.freeshell.org/google/>.


I see. Yes, I'm using google and thinking of this as a web forum.
Whoops.

Thanks to everyone for all the pointers about my code. It's a little
confusing (what with differences of opinion, etc.), but I think I'm
getting it. So far, I have reworked the code to try and incorporate
some of these suggestions, although I have not yet created all the
proper error-checking features. I'll add those as soon as I study up
enough to understand what you're recommending ;).

Here's the current, semi-reworked version:

#include <stdio.h>
/*written 13Apr06 by mwt
This program is intended to give the sum of the integers in an array of
length n,.
where n is input by the user.*/

int add_array(int arr[], int arr_size)
{
int j;
int total = 0;
for(j = 0; j < arr_size; j++)
{
total += arr[j];
}
return total;

}

int main(void)
{
int size;
printf("Input size of array>");
scanf("%d", &size);
int *array = malloc(size*sizeof(*array));
int i;
for(i=0; i<size; i++)
{
array[i] = i+1;
}

printf("Sum of array elements is %d.\n", add_array(array,
size));
free(array);
return 0;
}

It runs, but there is still some weirdness.

With my gcc compiler set with the flags -Wall -ansi -pedantic, it
complains about the "malloc" line in several ways:

add.c:23: warning: implicit declaration of function 'malloc'
add.c:23: warning: incompatible implicit declaration of built-in
function 'malloc'
add.c:23: warning: ISO C90 forbids mixed declarations and code

As well as the "free" line:

add.c:31: warning: implicit declaration of function 'free'

Apr 13 '06 #11

P: n/a
"mwt" <mi*********@gmail.com> writes:
<snip>
With my gcc compiler set with the flags -Wall -ansi -pedantic, it
complains about the "malloc" line in several ways:

add.c:23: warning: implicit declaration of function 'malloc'
add.c:23: warning: incompatible implicit declaration of built-in
function 'malloc'
add.c:23: warning: ISO C90 forbids mixed declarations and code

As well as the "free" line:

add.c:31: warning: implicit declaration of function 'free'


You have to include the prototypes for the malloc and free which are
found in stdlib.h, so put the line:

#include <stdlib.h>

at the beginning of your program to get rid of those warnings.

--
burton samograd kruhft .at. gmail
kruhft.blogspot.com www.myspace.com/kruhft metashell.blogspot.com
Apr 13 '06 #12

P: n/a
"Default User" <de***********@yahoo.com> writes:
osmium wrote:
"mwt" writes:

main()
{
int size;

printf("Input size of array>");
scanf("%d", &size);
int array[size];

Assuming that it works, I would say you are off to a good start.


You're pretty easy. What version of C allows both implicit declaration
of functions AND variable-length arrays?


gcc

--
burton samograd kruhft .at. gmail
kruhft.blogspot.com www.myspace.com/kruhft metashell.blogspot.com
Apr 13 '06 #13

P: n/a

"Roberto Waltman" <us****@rwaltman.net> wrote in message
news:sc********************************@4ax.com...
"mwt" <mi*********@gmail.com> wrote:
Hello. Today I wrote my first program in C. It adds up the elements in
an array. I am just beginning to learn this language. Any tips or
pointers about better ways to write/structure/format/etc. this code
would be much appreciated. Thanks.
mwt.


Compiling (under Linux) with "gcc -Wall -ansi -pedantic first.c"
produces a few warnings. I inserted them at the matching line.

#include <stdio.h>

int add_array(int arr[], int arr_size)
{
int j;
int total = 0;
for(j = 0; j < arr_size; j++)
total += arr[j];
return(total);

( The parenthesis are not necessary. I tend to use them here myself)

}

main()

first.c:14: warning: return type defaults to `int'
(Should be "int main(void)" if you do not process command line
parameters)
{
int size;

printf("Input size of array>");
scanf("%d", &size);
int array[size];

first.c:19: warning: ISO C89 forbids variable-size array `array'
first.c:19: warning: ISO C89 forbids mixed declarations and code
(Probably too early for you to bother about different versions of C,
but be aware that the language has changed over time)
int i;
for(i=0; i<size; i++)
{
array[i] = i+1;

}

printf("Sum of array elements is %d.\n", add_array(array,
size));

first.c:29: warning: control reaches end of non-void function
( missing return EXIT_SUCCESS; - defined in stdlib.h }
}


A few comments on style: be consistent. You use braces around the
single statement in the for() loop in the main function, (which is
good,) but not in a similar loop in add_array().

Likewise, you use a "double level" indentation for the function
blocks, but not for the for() loops. Pick a style and stick with it.

A few comments describing the program's purpose would be helpful. They
become much more important for more complex programs.

All in all, very good for a first program!


Agreed!
Now the OP might want to consider these two variations of his program:
1) Find the mean value (sum divided by size) of the items in the array.
2) What might happen if the array is real numbers instead of integers?

In (1), obviously the mean is unlikely to be an exact integer, so the answer
should be stated as a double. So his summation function, to become a
mean() method, might looks like:
double compute_mean( int *array, int size );
or for (2):
double compute_mean( double *array, int size );

However, adding up the numbers and then dividing by size could cause a
couple
of problems.
The obvious one is if size=0. OP: how would you handle this?
Another one is if there are n values, all greater than MAX_INT/n. OP: how
to handle this?
Another is if there are millions of values, and some are very small and
some are very large (i.e., LARGE_VALUE > SMALL_VALUE*10**16) OP: How to
handle this?
--
Fred L. Kleinschmidt
Boeing Associate Technical Fellow
Technical Architect, Software Reuse Project
Apr 13 '06 #14

P: n/a
"mwt" <mi*********@gmail.com> writes:
[...]
Thanks to everyone for all the pointers about my code. It's a little
confusing (what with differences of opinion, etc.), but I think I'm
getting it. So far, I have reworked the code to try and incorporate
some of these suggestions, although I have not yet created all the
proper error-checking features. I'll add those as soon as I study up
enough to understand what you're recommending ;).

Here's the current, semi-reworked version:
[snip] It runs, but there is still some weirdness.

With my gcc compiler set with the flags -Wall -ansi -pedantic, it
complains about the "malloc" line in several ways:

add.c:23: warning: implicit declaration of function 'malloc'
add.c:23: warning: incompatible implicit declaration of built-in
function 'malloc'
add.c:23: warning: ISO C90 forbids mixed declarations and code

As well as the "free" line:

add.c:31: warning: implicit declaration of function 'free'


As Burton Samograd mentioned, "#include <stdlib.h>" will fix the
warnings about malloc and free.

If you want C90 compatibility, you still need to avoid mixing
declarations and statements. For example, you have something like
(code mercilessly abbreviated to illustrate the point):

{
int size;
scanf("%d", &size);
int *array = malloc(size * sizeof *array);
...
}

Within the block, you have a delaration, a statement, and a
declaration, which is illegal in C90. (It's allowed in C99 <OT>and in
C++</OT>, and probably in GNU C.)

(OT is an abbreviation for "off-topic", since we don't discuss C++
here.)

There are (at least) two ways to fix this (other than using a C99
compiler and not worrying so much about portability):

1. Move all your declarations to the top of the block. If you have
any initializations that depend on preceding statements, change
them to assignments:

{
int size;
int *array;

scanf("%d", &size);
array = malloc(size * sizeof *array);
...
}

2. Create a nested block (a block is a statement):

{
int size;

scanf("%d", &size);
{
int *array = malloc(size * sizeof *array);
...
}
}

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Apr 13 '06 #15

P: n/a
mwt

Keith Thompson wrote:
"mwt" <mi*********@gmail.com> writes:
[...]
Thanks to everyone for all the pointers about my code. It's a little
confusing (what with differences of opinion, etc.), but I think I'm
getting it. So far, I have reworked the code to try and incorporate
some of these suggestions, although I have not yet created all the
proper error-checking features. I'll add those as soon as I study up
enough to understand what you're recommending ;).

Here's the current, semi-reworked version:

[snip]
It runs, but there is still some weirdness.

With my gcc compiler set with the flags -Wall -ansi -pedantic, it
complains about the "malloc" line in several ways:

add.c:23: warning: implicit declaration of function 'malloc'
add.c:23: warning: incompatible implicit declaration of built-in
function 'malloc'
add.c:23: warning: ISO C90 forbids mixed declarations and code

As well as the "free" line:

add.c:31: warning: implicit declaration of function 'free'


As Burton Samograd mentioned, "#include <stdlib.h>" will fix the
warnings about malloc and free.

If you want C90 compatibility, you still need to avoid mixing
declarations and statements. For example, you have something like
(code mercilessly abbreviated to illustrate the point):

{
int size;
scanf("%d", &size);
int *array = malloc(size * sizeof *array);
...
}

Within the block, you have a delaration, a statement, and a
declaration, which is illegal in C90. (It's allowed in C99 <OT>and in
C++</OT>, and probably in GNU C.)

(OT is an abbreviation for "off-topic", since we don't discuss C++
here.)

There are (at least) two ways to fix this (other than using a C99
compiler and not worrying so much about portability):

1. Move all your declarations to the top of the block. If you have
any initializations that depend on preceding statements, change
them to assignments:

{
int size;
int *array;

scanf("%d", &size);
array = malloc(size * sizeof *array);
...
}

2. Create a nested block (a block is a statement):

{
int size;

scanf("%d", &size);
{
int *array = malloc(size * sizeof *array);
...
}
}

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.


Keith -
I've tried to incorporate your suggestions. I have looked up and
attempted to understand the fgets and sscanf functions you recommended.
Here is my modified main function. It does compile without errors and
run. Is this closer to what you're describing?

int main(void)
{
int length;
char c[4];
int *array;
int i;

printf("Input length of array (max. 4 digits)>");
fflush(stdout);
fgets(c, 4, stdin);
sscanf(c, "%d", &length);
array = malloc(length*sizeof(*array));

for(i=0; i<length; i++)
{
array[i] = i+1;
}

printf("Sum of array elements is %d.\n", add_array(array,
length));
free(array);
return 0;
}

Apr 13 '06 #16

P: n/a
Burton Samograd wrote:
"Default User" <de***********@yahoo.com> writes:

You're pretty easy. What version of C allows both implicit
declaration of functions AND variable-length arrays?


gcc

That's no version of C I've ever heard of. Now, it may be the case it's
a C compiler with platform-specific, non-standard extensions.


Brian
Apr 13 '06 #17

P: n/a
"mwt" <mi*********@gmail.com> writes:
[...]
Keith -
I've tried to incorporate your suggestions. I have looked up and
attempted to understand the fgets and sscanf functions you recommended.
Here is my modified main function. It does compile without errors and
run. Is this closer to what you're describing?
Closer.

(BTW, don't quote the entire article to which you're replying; snip
out the parts that aren't relevant to your followup. In particular,
don't quote the signature unless you're comenting on it.)
int main(void)
{
int length;
char c[4];
int *array;
The name "array" is potentially misleading. The variable points to an
array; it itself is a pointer.
int i;

printf("Input length of array (max. 4 digits)>");
fflush(stdout);
fgets(c, 4, stdin);
I'd make the array bigger. Remember, you're trying to read an entire
line, and the string needs to hold the trailing new-line characters as
well.

Also, 4 is a "magic number". Use a macro to define the size of
your array:

#define MAX_LEN 100
char c[MAX_LEN];
...
fgets(c, MAX_LEN, stdin);
or even:
fgets(c, sizeof c, stdin);

(The latter fails if c is a pointer to an array rather than an actual
array.0
sscanf(c, "%d", &length);
What happens if the user enters "xyz"? sscan() returns a result; use
it.
array = malloc(length*sizeof(*array));
What happens if the user enters "0"? Or "-123"?
for(i=0; i<length; i++)
{
array[i] = i+1;
}

printf("Sum of array elements is %d.\n", add_array(array,
length));
Long lines can be a problem, especially when posting to Usenet, where
software can split lines at arbitrary points. I'd write this as:

printf("Sum of array elements is %d.\n",
add_array(array, length));

though opinions vary considerably on how to indent continuation lines
like this.
free(array);
return 0;
}


--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Apr 13 '06 #18

P: n/a
mwt wrote:
Hello. Today I wrote my first program in C. It adds up the elements in
an array. I am just beginning to learn this language. Any tips or
pointers about better ways to write/structure/format/etc. this code
would be much appreciated. Thanks.
mwt.

#include <stdio.h>

int add_array(int arr[], int arr_size)


Hint: Which one of the statements

x = add_array(a, length);

and

x = array_sum(a, length);

do you think makes most sense?

When choosing a name of a subroutine that returns a value and has no
side effect, try to concentrate on the returned value. What is
returned?.. the array sum. (You may also want to look up the
command-query principle.)
August

--
I am the "ILOVEGNU" signature virus. Just copy me to your signature.
This email was infected under the terms of the GNU General Public License.
Apr 13 '06 #19

P: n/a
mwt

Keith Thompson wrote:
The name "array" is potentially misleading. The variable points to an
array; it itself is a pointer.
int i;

printf("Input length of array (max. 4 digits)>");
fflush(stdout);
fgets(c, 4, stdin);
I'd make the array bigger. Remember, you're trying to read an entire
line, and the string needs to hold the trailing new-line characters as
well.

Also, 4 is a "magic number". Use a macro to define the size of
your array:

#define MAX_LEN 100
char c[MAX_LEN];
...
fgets(c, MAX_LEN, stdin);
or even:
fgets(c, sizeof c, stdin);

(The latter fails if c is a pointer to an array rather than an actual
array.0
sscanf(c, "%d", &length);


What happens if the user enters "xyz"? sscan() returns a result; use
it.

array = malloc(length*sizeof(*array));
What happens if the user enters "0"? Or "-123"?


I think the new code I wrote addresses these issues. Now, if the user
inputs non-digits, the program exits (not the best way to handle
things, but at least it works). I think that "0" is a valid digit to
input in this case, so I allow it. Certainly negative numbers would be
interesting to be able to process properly, although I'm not sure how
to go about it.
August Karlstrom wrote:
x = array_sum(a, length); When choosing a name of a subroutine that returns a value and has no
side effect, try to concentrate on the returned value. What is
returned?.. the array sum. (You may also want to look up the
command-query principle.)


That makes sense. I've changed the function name to suit.

Here's the current iteration of this exercise. Thanks, again, to
everyone for all the input. Including the stuff on how to properly post
to the group.

#include <stdio.h>
#include <stdlib.h>
/* written 13Apr06 by mwt
*
* This program is intended to give the sum
* of the integers in an array of length n,.
* where n is input by the user.
*/

#define MAX_LEN 100

int array_sum(int *arr, int arr_length)
{
int j;
int total = 0;
for(j = 0; j < arr_length; j++)
{
total += arr[j];
}
return total;

}

int main(void)
{
int length;
char c[MAX_LEN];
int *int_array;
int i;
int sc;

printf("Input length of array>");
fflush(stdout);
fgets(c, MAX_LEN, stdin);
sc = sscanf(c, "%d", &length);
if(sc > 0 && length >=0)
{
int_array = malloc(length*sizeof(*int_array));

for(i=0; i<length; i++)
{
int_array[i] = i+1;
}

printf("Sum of array elements is %d.\n",
array_sum(int_array, length));
free(int_array);
}
else
{
printf("Invalid input.\n");
}
return 0;
}

Apr 13 '06 #20

P: n/a
mwt

Fred Kleinschmidt wrote:
Now the OP might want to consider these two variations of his program:
1) Find the mean value (sum divided by size) of the items in the array.
2) What might happen if the array is real numbers instead of integers?

In (1), obviously the mean is unlikely to be an exact integer, so the answer
should be stated as a double. So his summation function, to become a
mean() method, might looks like:
double compute_mean( int *array, int size );
or for (2):
double compute_mean( double *array, int size );


Here's a new function to compute the mean. In the main function, I've
precluded "0" as valid input in order to get around the divide by zero
problem. The cast to double in the return statement seems to be
necessary to make it work, but I don't know if this is the best way to
approach it.

double compute_mean(int *arr, int arr_length)
{
int j;
int total = 0;
for(j = 0; j < arr_length; j++)
{
total += arr[j];
}
return (double) total / arr_length;

}

Apr 14 '06 #21

P: n/a
"mwt" <mi*********@gmail.com> writes:
Keith Thompson wrote: [...]
> array = malloc(length*sizeof(*array));


What happens if the user enters "0"? Or "-123"?


I think the new code I wrote addresses these issues. Now, if the user
inputs non-digits, the program exits (not the best way to handle
things, but at least it works). I think that "0" is a valid digit to
input in this case, so I allow it. Certainly negative numbers would be
interesting to be able to process properly, although I'm not sure how
to go about it.


You probably don't want to allow length to be 0. C doesn't support
zero-sized objects. In particular, if length==0, you call malloc(0),
which can yield either NULL or a valid pointer to some (unusable)
chunk of allocated memory. Since you don't actually access the array
in that case,n it's not a real problem, but it's probably better to
avoid it altogether.

[snip] sc = sscanf(c, "%d", &length);
if(sc > 0 && length >=0)

[snip]

sscanf() returns the number of input items assigned. It would be a
bit clearer, I think, to check that it returns exactly the number
of items you expected:

if (sc == 1 && length > 0)

This is more easily extended to reading multiple items:

sc = sscanf(c, "%d%d", &x, &y);
if (sc == 2) {
/* got both items */
}
else {
/* an error occurred */
}

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Apr 14 '06 #22

P: n/a
"mwt" <mi*********@gmail.com> writes:
[...]
Here's a new function to compute the mean. In the main function, I've
precluded "0" as valid input in order to get around the divide by zero
problem. The cast to double in the return statement seems to be
necessary to make it work, but I don't know if this is the best way to
approach it.

double compute_mean(int *arr, int arr_length)
{
int j;
int total = 0;
for(j = 0; j < arr_length; j++)
{
total += arr[j];
}
return (double) total / arr_length;

}


Yes, this is one of the few cases where a cast is justified.

Without it (as you've probably seen), the expression "total / arr_length"
is evaluated as an int, which means the result is truncated. The "/"
operator takes two operands of the *same* numeric type, and yields a
result of the same type. Converting one operand to double forces the
other operand to be implicitly converted to double, yielding a double
result.

For the sake of symmetry, I might cast both operands:

return (double)total / (double)arr_length;

but it makes no real difference.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Apr 14 '06 #23

P: n/a

"mwt" <mi*********@gmail.com> wrote in message
news:11*********************@i39g2000cwa.googlegro ups.com...

Fred Kleinschmidt wrote:
Now the OP might want to consider these two variations of his program:
1) Find the mean value (sum divided by size) of the items in the array.
2) What might happen if the array is real numbers instead of integers?

In (1), obviously the mean is unlikely to be an exact integer, so the
answer
should be stated as a double. So his summation function, to become a
mean() method, might looks like:
double compute_mean( int *array, int size );
or for (2):
double compute_mean( double *array, int size );


Here's a new function to compute the mean. In the main function, I've
precluded "0" as valid input in order to get around the divide by zero
problem. The cast to double in the return statement seems to be
necessary to make it work, but I don't know if this is the best way to
approach it.

double compute_mean(int *arr, int arr_length)
{
int j;
int total = 0;
for(j = 0; j < arr_length; j++)
{
total += arr[j];
}
return (double) total / arr_length;

}

The above code wil definitely have problems finding the mean of this array:
int values[4] = {MAXINT, MAXINT, (MAXINT-2), (MAXINT-2)};
The actual value is (MAXINT-1), which is representable. But the above code
will overflow.
So a safer code is:
double compute_mean(int *arr, int arr_length)
{
int j;
double total = 0.0;
for(j = 0; j < arr_length; j++)
{
total += (double)arr[j]/arr_length;
}
return total;
}

However, it is quite inefficient for most arrays, and will encounter a lot
of
roundoff and/or truncation error.
There are other ways to program it so that it is much more efficient
and has a minimal roundoff error. One way is to accumulate the integer sum
until the next addition would overflow, then divide that sum by arr_length,
and keep adding these partial means together.

However, even that is not sufficient if the magnitudes of values in the
array
differ greatly. Try adding 10e-18 to 1.0 and see what the result is.
But what if there are 100000000 values of 10e-18 in the array, and one
value of 1.0? The order of summation is important.
--
Fred L. Kleinschmidt
Boeing Associate Technical Fellow
Technical Architect, Software Reuse Project


Apr 14 '06 #24

P: n/a
Fred Kleinschmidt opined:

"mwt" <mi*********@gmail.com> wrote in message
news:11*********************@i39g2000cwa.googlegro ups.com...

Fred Kleinschmidt wrote:
Now the OP might want to consider these two variations of his
program: 1) Find the mean value (sum divided by size) of the items
in the array. 2) What might happen if the array is real numbers
instead of integers?

In (1), obviously the mean is unlikely to be an exact integer, so
the answer
should be stated as a double. So his summation function, to become
a mean() method, might looks like:
double compute_mean( int *array, int size );
or for (2):
double compute_mean( double *array, int size );

Here's a new function to compute the mean. In the main function,
I've precluded "0" as valid input in order to get around the divide
by zero problem. The cast to double in the return statement seems to
be necessary to make it work, but I don't know if this is the best
way to approach it.

double compute_mean(int *arr, int arr_length)
{
int j;
int total = 0;
for(j = 0; j < arr_length; j++)
{
total += arr[j];
}
return (double) total / arr_length;

}

The above code wil definitely have problems finding the mean of this
array: int values[4] = {MAXINT, MAXINT, (MAXINT-2), (MAXINT-2)};


You surely mean INT_MAX from <limits.h>?
The actual value is (MAXINT-1), which is representable. But the above
code will overflow.
So a safer code is:
double compute_mean(int *arr, int arr_length)
{
int j;
double total = 0.0;
for(j = 0; j < arr_length; j++)
{
total += (double)arr[j]/arr_length;
}
return total;
}

However, it is quite inefficient for most arrays, and will encounter
a lot of
roundoff and/or truncation error.
There are other ways to program it so that it is much more efficient
and has a minimal roundoff error. One way is to accumulate the
integer sum until the next addition would overflow, then divide that
sum by arr_length, and keep adding these partial means together.

However, even that is not sufficient if the magnitudes of values in
the array
differ greatly. Try adding 10e-18 to 1.0 and see what the result is.
But what if there are 100000000 values of 10e-18 in the array, and
one value of 1.0? The order of summation is important.


--
Now it's time to say goodbye
To all our company...
M-I-C (see you next week!)
K-E-Y (Why? Because we LIKE you!)
M-O-U-S-E.

<http://clc-wiki.net/wiki/Introduction_to_comp.lang.c>

Apr 14 '06 #25

P: n/a
Keith Thompson <ks***@mib.org> writes:
"mwt" <mi*********@gmail.com> writes:
[...]
Here's a new function to compute the mean. In the main function, I've
precluded "0" as valid input in order to get around the divide by zero
problem. The cast to double in the return statement seems to be
necessary to make it work, but I don't know if this is the best way to
approach it.

double compute_mean(int *arr, int arr_length)
{
int j;
int total = 0;
for(j = 0; j < arr_length; j++)
{
total += arr[j];
}
return (double) total / arr_length;

}


Yes, this is one of the few cases where a cast is justified.

Without it (as you've probably seen), the expression "total / arr_length"
is evaluated as an int, which means the result is truncated. The "/"
operator takes two operands of the *same* numeric type, and yields a
result of the same type. Converting one operand to double forces the
other operand to be implicitly converted to double, yielding a double
result.

For the sake of symmetry, I might cast both operands:

return (double)total / (double)arr_length;

but it makes no real difference.


Even if I decided to cast just the left operand, I'd at least want to
bring the cast closer to the expression I'm converting, as you have
done, to make it clearer... the original statement seems liable to be
misread as symantically equivalent to (double(total / arr_length)

--
Micah J. Cowan
Programmer, musician, typesetting enthusiast, gamer...
http://micah.cowan.name/
Apr 14 '06 #26

P: n/a
Micah Cowan <mi***@cowan.name> writes:
Keith Thompson <ks***@mib.org> writes:

[...]
For the sake of symmetry, I might cast both operands:

return (double)total / (double)arr_length;

but it makes no real difference.


Even if I decided to cast just the left operand, I'd at least want to
bring the cast closer to the expression I'm converting, as you have
done, to make it clearer... the original statement seems liable to be
misread as symantically equivalent to (double(total / arr_length)


You missed a right parenthesis;

(double)(total / arr_length)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Apr 14 '06 #27

This discussion thread is closed

Replies have been disabled for this discussion.