Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #12332 > unrolled thread
| Started by | flebber <flebber.crue@gmail.com> |
|---|---|
| First post | 2011-10-31 03:35 -0700 |
| Last post | 2011-11-21 02:39 -0500 |
| Articles | 15 — 9 participants |
Back to article view | Back to comp.lang.c
Using ternary and summing array flebber <flebber.crue@gmail.com> - 2011-10-31 03:35 -0700
Re: Using ternary and summing array flebber <flebber.crue@gmail.com> - 2011-10-31 04:06 -0700
Re: Using ternary and summing array Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-10-31 15:06 +0000
Re: Using ternary and summing array pete <pfiland@mindspring.com> - 2011-11-01 04:37 -0500
Re: Using ternary and summing array Keith Thompson <kst-u@mib.org> - 2011-11-01 16:36 -0700
Re: Using ternary and summing array flebber <flebber.crue@gmail.com> - 2011-10-31 04:04 -0700
Re: Using ternary and summing array Jean-Christophe <5.d@free.fr> - 2011-10-31 04:16 -0700
Re: Using ternary and summing array Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-10-31 15:00 +0000
Re: Using ternary and summing array flebber <flebber.crue@gmail.com> - 2011-10-31 16:11 -0700
Re: Using ternary and summing array James Kuyper <jameskuyper@verizon.net> - 2011-10-31 21:49 -0400
Re: Using ternary and summing array Kenneth Brody <kenbrody@spamcop.net> - 2011-11-03 12:04 -0400
Re: Using ternary and summing array Kaz Kylheku <kaz@kylheku.com> - 2011-11-03 17:03 +0000
Re: Using ternary and summing array Kenneth Brody <kenbrody@spamcop.net> - 2011-11-08 13:08 -0500
Re: Using ternary and summing array James Kuyper <jameskuyper@verizon.net> - 2011-10-31 07:46 -0400
Re: Using ternary and summing array David Thompson <dave.thompson2@verizon.net> - 2011-11-21 02:39 -0500
| From | flebber <flebber.crue@gmail.com> |
|---|---|
| Date | 2011-10-31 03:35 -0700 |
| Subject | Using ternary and summing array |
| Message-ID | <26bf4806-b232-4878-810b-55f3d3926c9f@p20g2000prm.googlegroups.com> |
Hi
I am learning C. I am trying to sum an array with the values returned
from a loop. Can I use the "?" operator as part of a loop; by
experimentation I know I can't put the increment in the loop.
doing ((i % 3 == 0)||(i % 5 == 0)) ? sum+=a[i] :i++ ; never actually
finished, I think I created an infinite loop.
PS I was following the example from here
http://www.tutorialspoint.com/ansi_c/ternary_operator_examples.htm
So I have come to this this solution, I think the problem is that my
array a[] is assigned as a one element array and since the first value
returns false it gets 0 and exits. Is this right? If it is how do i
assign an array to have an unknown number of entries?
A kick in the right direction appreciated
#include <stdio.h>
int a[],i,sum=0;
int main()
{
while(i < 1000)
{
((i % 3 == 0)||(i % 5 == 0)) ? sum+=a[i] :0 ;
i++;
}
printf("The sum is %d\n",sum);
return 0;
}
Sayth
[toc] | [next] | [standalone]
| From | flebber <flebber.crue@gmail.com> |
|---|---|
| Date | 2011-10-31 04:06 -0700 |
| Message-ID | <6615b0de-8283-486e-acaf-fa21560ff96d@p14g2000pra.googlegroups.com> |
| In reply to | #12332 |
On Oct 31, 9:35 pm, flebber <flebber.c...@gmail.com> wrote:
> Hi
>
> I am learning C. I am trying to sum an array with the values returned
> from a loop. Can I use the "?" operator as part of a loop; by
> experimentation I know I can't put the increment in the loop.
>
> doing ((i % 3 == 0)||(i % 5 == 0)) ? sum+=a[i] :i++ ; never actually
> finished, I think I created an infinite loop.
> PS I was following the example from herehttp://www.tutorialspoint.com/ansi_c/ternary_operator_examples.htm
>
> So I have come to this this solution, I think the problem is that my
> array a[] is assigned as a one element array and since the first value
> returns false it gets 0 and exits. Is this right? If it is how do i
> assign an array to have an unknown number of entries?
>
> A kick in the right direction appreciated
>
> #include <stdio.h>
> int a[],i,sum=0;
>
> int main()
> {
> while(i < 1000)
> {
> ((i % 3 == 0)||(i % 5 == 0)) ? sum+=a[i] :0 ;
> i++;
> }
> printf("The sum is %d\n",sum);
> return 0;
>
> }
>
> Sayth
I created a working solution with an if statement but I would still
really love to know if I could use the "?" to acheive the same result.
Working solution
#include <stdio.h>
int i,sum=0;
int total;
int main()
{
while(i < 1000)
{
if ((i % 3 == 0)||(i % 5 == 0)){
sum += i;
}
i++;
}
printf("The sum is %d\n",sum);
return 0;
}
Sayth
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2011-10-31 15:06 +0000 |
| Message-ID | <0.99333bc217a9adde7846.20111031150653GMT.87k47ldwtu.fsf@bsb.me.uk> |
| In reply to | #12337 |
flebber <flebber.crue@gmail.com> writes:
<snip>
> On Oct 31, 9:35 pm, flebber <flebber.c...@gmail.com> wrote:
> I created a working solution with an if statement but I would still
> really love to know if I could use the "?" to acheive the same result.
Yes, but it won't be any clearer.
> Working solution
>
>
> #include <stdio.h>
> int i,sum=0;
> int total;
You don't use total. It will just confuse people.
> int main()
> {
> while(i < 1000)
> {
> if ((i % 3 == 0)||(i % 5 == 0)){
> sum += i;
You can write
sum += (i % 3 == 0 || i % 5 == 0) ? i : 0;
Since logical expressions are either 0 or 1, you can also write
sum += (i % 3 == 0 || i % 5 == 0) * i;
but both are, in my opinion, inferior to a simple 'if'.
What would make it clearer is to use a 'for' loop and to avoid having
"global" (technically file scope) variales. Simple counted loops are
best expressed using 'for'.
> }
> i++;
> }
> printf("The sum is %d\n",sum);
> return 0;
> }
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | pete <pfiland@mindspring.com> |
|---|---|
| Date | 2011-11-01 04:37 -0500 |
| Message-ID | <4EAFBDCD.7264@mindspring.com> |
| In reply to | #12337 |
flebber wrote:
> I created a working solution with an if statement but I would still
> really love to know if I could use the "?" to acheive the same result.
> if ((i % 3 == 0)||(i % 5 == 0)){
> sum += i;
> }
If that is truly your goal:
sum += ((i % 3 == 0)||(i % 5 == 0)) ? i : 0;
--
pete
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2011-11-01 16:36 -0700 |
| Message-ID | <lnlirzifea.fsf@nuthaus.mib.org> |
| In reply to | #12431 |
pete <pfiland@mindspring.com> writes:
> flebber wrote:
>> I created a working solution with an if statement but I would still
>> really love to know if I could use the "?" to acheive the same result.
>
>> if ((i % 3 == 0)||(i % 5 == 0)){
>> sum += i;
>> }
>
> If that is truly your goal:
>
> sum += ((i % 3 == 0)||(i % 5 == 0)) ? i : 0;
Yes, but frankly it's a foolish goal. The "if" form is easier to
read -- though personally I'd find it even easier with more whitespace
and fewer parentheses:
if (i % 3 == 0 || i % 5 == 0) {
sum += i;
}
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | flebber <flebber.crue@gmail.com> |
|---|---|
| Date | 2011-10-31 04:04 -0700 |
| Message-ID | <1beba051-c0cd-4cbf-89c0-c54eb3cef85f@t38g2000prg.googlegroups.com> |
| In reply to | #12332 |
On Oct 31, 9:35 pm, flebber <flebber.c...@gmail.com> wrote:
> Hi
>
> I am learning C. I am trying to sum an array with the values returned
> from a loop. Can I use the "?" operator as part of a loop; by
> experimentation I know I can't put the increment in the loop.
>
> doing ((i % 3 == 0)||(i % 5 == 0)) ? sum+=a[i] :i++ ; never actually
> finished, I think I created an infinite loop.
> PS I was following the example from herehttp://www.tutorialspoint.com/ansi_c/ternary_operator_examples.htm
>
> So I have come to this this solution, I think the problem is that my
> array a[] is assigned as a one element array and since the first value
> returns false it gets 0 and exits. Is this right? If it is how do i
> assign an array to have an unknown number of entries?
>
> A kick in the right direction appreciated
>
> #include <stdio.h>
> int a[],i,sum=0;
>
> int main()
> {
> while(i < 1000)
> {
> ((i % 3 == 0)||(i % 5 == 0)) ? sum+=a[i] :0 ;
> i++;
> }
> printf("The sum is %d\n",sum);
> return 0;
>
> }
>
> Sayth
Well I solved it using an if statement, but I would still love to know
if there is a way to do it with the "?".
Working Solution
#include <stdio.h>
int i,sum=0;
int total;
int main()
{
while(i < 1000)
{
if ((i % 3 == 0)||(i % 5 == 0)){
sum += i;
}
i++;
}
printf("The sum is %d\n",sum);
return 0;
}
Cheers
Sayth
[toc] | [prev] | [next] | [standalone]
| From | Jean-Christophe <5.d@free.fr> |
|---|---|
| Date | 2011-10-31 04:16 -0700 |
| Message-ID | <9f0bff2f-ccec-4c4d-ae8d-aef2a45216fb@s2g2000yqd.googlegroups.com> |
| In reply to | #12332 |
On 31 oct, 11:35, flebber
> #include <stdio.h>
> int a[],i,sum=0;
'a' size is undefined.
> int main()
> {
> while(i < 1000)
'i' is not initialized.
> {
> ((i % 3 == 0)||(i % 5 == 0)) ? sum+=a[i] :0 ;
1) You can't just write (a)?b:c;
2) 'a' is not initialized.
> i++;
> }
> printf("The sum is %d\n",sum);
> return 0;
> }
----
If you really want to use (a)?b:c; I suggest
#define SIZE 1000
int main(void)
{
int a[SIZE], i, sum;
// here you must initialize 'a' values
// ...
// loop
for( sum=i=0; i < SIZE; ++i )
sum += ( !(i % 3) || !(i % 5) ) ? a[i] : 0;
printf("The sum is %d\n",sum);
return 0;
}
----
Now, since it's pointless adding sum+=0 you could
for( sum=i=0; i < SIZE; ++i )
if( !(i % 3) || !(i % 5) ) sum += a[i];
Anyway, what are the 1000 values of a[i] ?
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2011-10-31 15:00 +0000 |
| Message-ID | <0.e5f5b7e50e88e1c951ce.20111031150044GMT.87pqhddx43.fsf@bsb.me.uk> |
| In reply to | #12340 |
Jean-Christophe <5.d@free.fr> writes:
> On 31 oct, 11:35, flebber
>
>> #include <stdio.h>
>> int a[],i,sum=0;
>
> 'a' size is undefined.
>
>> int main()
>> {
>> while(i < 1000)
>
> 'i' is not initialized.
It is. It's got static storage duration and hence will be zero
initialised. It should not be "out there" and, if it were defined where
it should be, (in main) you'd be right.
>> {
>> ((i % 3 == 0)||(i % 5 == 0)) ? sum+=a[i] :0 ;
>
> 1) You can't just write (a)?b:c;
I know what you mean -- it's not a good idea -- but it's perfectly valid
C.
> 2) 'a' is not initialized.
It is. Both 'i' and 'a' are initialised in the op's code. That 'a' is
both defined and initialised is an odd quirk of C and that quirk should
definitely not be used by anyone.
>> i++;
>> }
>> printf("The sum is %d\n",sum);
>> return 0;
>> }
<snip>
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | flebber <flebber.crue@gmail.com> |
|---|---|
| Date | 2011-10-31 16:11 -0700 |
| Message-ID | <005a4456-b4ba-4f38-a513-67c9ffeedcf4@s35g2000pra.googlegroups.com> |
| In reply to | #12340 |
> If you really want to use (a)?b:c; I suggest
>
> #define SIZE 1000
> int main(void)
> {
> int a[SIZE], i, sum;
>
> // here you must initialize 'a' values
> // ...
>
> // loop
> for( sum=i=0; i < SIZE; ++i )
> sum += ( !(i % 3) || !(i % 5) ) ? a[i] : 0;
>
> printf("The sum is %d\n",sum);
> return 0;
Thank You Jean-Christophe, I like the way you use the define as I
think it makes it clear and readable.
> No, the first value does not "return false". Your code attempts to read
> the first 1000 elements of a[], regardless of whether or not it actually
> has 1000 elements. So what happens is that it tries to read pieces of
> memory that aren't actually part of a[]. As a result, the behavior of
> your program is not defined by the C standard. This is bad - very bad.
> Don't do that.
James thanks for explaining that. I had the feeling I was doing it
wrong but wasn't quite sure where it was going wrong.
> extern int a[];
So this declares my array as a global value. I can then assign a
value(size of array) to it locally. This would then mean that if I had
5 different functions they could all have their own size declared of
array a[] locally? May not be the best idea but I could do this?
> int three_five_sum(
> int a[],
> int n
> ){
> // body of function.
> }
With this skeleton shouldn't I declare int a[1000], ?
> Try the following: write a
> function that takes two pointer arguments, a and b, and a count. For
> each value of i from 0 to count-1, it adds something to sum. However, if
> i is a multiple of 3 or 5, it adds a[i] to sum; otherwise, it adds b[i]
> to sum.
Working on it... not close yet but will get there, having issues with
local variables.
#include <stdio.h>
#define limit 1000;
int two_pointer_args(int, int); /* function using two ints */
int main()
{
two_pointer_args(int i, int j);
i, j = 0;
int i_total=0;
int j_total=0;
{
while (i < limit)
{
if ((i % 3 == 0)|| (i % 5 == 0))
{
i_total+=i;
}
else
{
j_total = i + j;
}
i++;
}
printf(" The sum of i was %d and the sum of j was %d\n", i_total,
j_total);
}
return 0;
}
Thanks for all the help Sayth.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2011-10-31 21:49 -0400 |
| Message-ID | <j8nj6g$rfe$1@dont-email.me> |
| In reply to | #12417 |
On 10/31/2011 07:11 PM, flebber wrote:
...
>> extern int a[];
>
> So this declares my array as a global value. I can then assign a
> value(size of array) to it locally.
No, that declaration REQUIRES that 'a' be a global variable. You can
define it as a global variable in some other module, but you can never
assign it; C doesn't allow assignment of arrays. Once you've defined the
array, you can then assign values to each element of the array, separately.
> ... This would then mean that if I had
> 5 different functions they could all have their own size declared of
> array a[] locally? May not be the best idea but I could do this?
No, only the definition of 'a' can give it a size, and the size that it
is given by the definition is the one and only correct size for that
array. You can declare 'a' in multiple different modules, none of which
know the size, but you need to make sure that none of those modules try
to use a part of the array that doesn't exist.
>> int three_five_sum(
>> int a[],
>> int n
>> ){
>> // body of function.
>> }
>
> With this skeleton shouldn't I declare int a[1000], ?
You need to either define or dynamically allocate an array of at least n
ints, somewhere, but that array doesn't need to be defined with a name
of 'a'. 'a' is simply the name of a local pointer variable that is
initialized with a copy of the pointer value passed to three_five_sum()
as it's first argument. Example:
int main(void)
{
int bunny[256];
// Fill in values for bunny
// Calculate the sum for the middle 128 elements of bunny:
int sum = three_five_sum(bunny+64, 128);
// rest of program
}
>> Try the following: write a
>> function that takes two pointer arguments, a and b, and a count. For
>> each value of i from 0 to count-1, it adds something to sum. However, if
>> i is a multiple of 3 or 5, it adds a[i] to sum; otherwise, it adds b[i]
>> to sum.
>
> Working on it... not close yet but will get there, having issues with
> local variables.
>
> #include <stdio.h>
> #define limit 1000;
>
> int two_pointer_args(int, int); /* function using two ints */
> int main()
>
> {
> two_pointer_args(int i, int j);
This declares a function named two_pointer_args which takes two
arguments, both of which are integers, not pointers.
Contrary to what I think you were trying to do, the lines after this are
NOT interpreted as a definition of that function. First of all, the ';'
terminates the declaration, so everything after this point is part of
the main() function body, and has nothing to do with two_pointer_args().
Secondly, even if you had left out the ';', it wouldn't have worked. You
can declare the function within main() (though I think it's better to
declare it outside of main()), and you can call it from main(), but you
cannot define it inside main(); you have to define it somewhere else.
> i, j = 0;
That line does not do what you think it does. It retrieves the value of
'i', and then discards it. Then it sets j to 0. Read up on the comma
operator.
> int i_total=0;
> int j_total=0;
You're calculating two different totals. I was talking about calculating
a single total.
> {
> while (i < limit)
> {
> if ((i % 3 == 0)|| (i % 5 == 0))
> {
> i_total+=i;
> }
> else
> {
> j_total = i + j;
> }
The whole point of my suggestion was to create an example where it would
be natural to use the ?: ternary operator. If you had only one variable,
named 'total', and if you had declared the arguments as pointers named a
and b, then you could have written:
if( i%3 == 0 || i%5 == 0)
total += a[i];
else
total += b[i];
Now, that code can be re-written to use the ?: operator, and it's a very
natural thing to do. Figure out how, and you'll have a much better
understanding of what that operator is all about.
--
James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Kenneth Brody <kenbrody@spamcop.net> |
|---|---|
| Date | 2011-11-03 12:04 -0400 |
| Message-ID | <BNCdnQuM3pwLJi_TnZ2dnUVZ_vSdnZ2d@bestweb.net> |
| In reply to | #12340 |
On 10/31/2011 7:16 AM, Jean-Christophe wrote:
> On 31 oct, 11:35, flebber
>
>> #include<stdio.h>
>> int a[],i,sum=0;
>
> 'a' size is undefined.
True. (Though my compiler creates it size zero. See below.)
>> int main()
>> {
>> while(i< 1000)
>
> 'i' is not initialized.
Because "i" is declared with global scope, it is initialized to zero.
>> {
>> ((i % 3 == 0)||(i % 5 == 0)) ? sum+=a[i] :0 ;
>
> 1) You can't just write (a)?b:c;
Yes, you can.
> 2) 'a' is not initialized.
Well, a[] has no defined size. However, if it were defined properly, it,
too, would be initialized to all zeros, due to its global scope.
Note that my compiler creates a[] with zero members.
However, my compiler acts "strange" on this point.
==========
#include <stdio.h>
int a[];
int main(void)
{
printf("%ld\n",(long)sizeof(a));
}
==========
The above gives no errors or warnings, even at max warning level, and prints
"0".
However, changing it to "int a[0];" gives an error "cannot allocate an array
of constant size 0" and the warning "sizeof returns 0", even at minimum
warning level.
Further investigation shows that my compiler seems to treat "int a[];" the
same as "extern int a[];". Is that "legal"?
[...]
--
Kenneth Brody
[toc] | [prev] | [next] | [standalone]
| From | Kaz Kylheku <kaz@kylheku.com> |
|---|---|
| Date | 2011-11-03 17:03 +0000 |
| Message-ID | <20111103121523.385@kylheku.com> |
| In reply to | #12595 |
On 2011-11-03, Kenneth Brody <kenbrody@spamcop.net> wrote:
> Note that my compiler creates a[] with zero members.
>
> However, my compiler acts "strange" on this point.
>
>==========
> #include <stdio.h>
>
> int a[];
>
> int main(void)
> {
> printf("%ld\n",(long)sizeof(a));
> }
>==========
Do you have some tools so you see what the size of a is in the translated
object file? (Is it in the object file?)
This might be a degenerate case which has no meaning due to a possible flaw in
the standard.
Under 6.9.2 we have this text:
A declaration of an identifier for an object that has file scope without an
initializer, and without a storage-class specifier or with the storage-class
specifier static, constitutes a tentative definition. If a translation unit
contains one or more tentative definitions for an identifier, and the
translation unit contains no external definition for that identifier, then the
behavior is exactly as if the translation unit contains a file scope
declaration of that identifier, with the composite type as of the end of the
translation unit, with an initializer equal to 0.
But an array cannot have an initializer equal to 0:
int a[] = 0; // invalid!
The second example for this section states the intent:
If at the end of the translation unit containing
int i[];
the array i still has incomplete type, the implicit initializer causes it to
have one element, which is set to zero on program startup.
This would be the case if the implicit initializer were { 0 }. The intent
is clear from the example, but for the text to bear it out, we have to
believe that "an initializer equal to zero" refers to a specific choice
of initializer such as { 0 }.
> Further investigation shows that my compiler seems to treat "int a[];" the
> same as "extern int a[];". Is that "legal"?
I would avoid this situation, since only a non-normative example gives it
a clear meaning.
Compiler writers, however, should pay careful attention to examples and
footnotes.
What does your compiler do if, at the end of the translation unit, you
add:
int a[] = { 0 };
?
[toc] | [prev] | [next] | [standalone]
| From | Kenneth Brody <kenbrody@spamcop.net> |
|---|---|
| Date | 2011-11-08 13:08 -0500 |
| Message-ID | <eaWdnVSLyfLV7STTnZ2dnUVZ_rGdnZ2d@bestweb.net> |
| In reply to | #12599 |
On 11/3/2011 1:03 PM, Kaz Kylheku wrote:
> On 2011-11-03, Kenneth Brody<kenbrody@spamcop.net> wrote:
>> Note that my compiler creates a[] with zero members.
>>
>> However, my compiler acts "strange" on this point.
>>
>> ==========
>> #include<stdio.h>
>>
>> int a[];
>>
>> int main(void)
>> {
>> printf("%ld\n",(long)sizeof(a));
>> }
>> ==========
>
> Do you have some tools so you see what the size of a is in the translated
> object file? (Is it in the object file?)
"a" is not in the resulting asm/obj file. (And the 2nd parameter to printf
is a constant zero.)
> This might be a degenerate case which has no meaning due to a possible flaw in
> the standard.
>
> Under 6.9.2 we have this text:
>
> A declaration of an identifier for an object that has file scope without an
> initializer, and without a storage-class specifier or with the storage-class
> specifier static, constitutes a tentative definition. If a translation unit
> contains one or more tentative definitions for an identifier, and the
> translation unit contains no external definition for that identifier, then the
> behavior is exactly as if the translation unit contains a file scope
> declaration of that identifier, with the composite type as of the end of the
> translation unit, with an initializer equal to 0.
>
> But an array cannot have an initializer equal to 0:
>
> int a[] = 0; // invalid!
[...]
>> Further investigation shows that my compiler seems to treat "int a[];" the
>> same as "extern int a[];". Is that "legal"?
>
> I would avoid this situation, since only a non-normative example gives it
> a clear meaning.
Well, 6.9.2 appears to say that it's "legal" in that it's a "tentative
definition".
As long as I don't actually do anything with the tentatively-defined
variable, the compiler doesn't have a problem. Of course, as soon as I try
to use it, I get an "unresolved external symbol" upon linking. Doesn't that
violate 6.9.2?
(Not that I would recommend coding that way, of course.)
> Compiler writers, however, should pay careful attention to examples and
> footnotes.
>
> What does your compiler do if, at the end of the translation unit, you
> add:
>
> int a[] = { 0 };
If that comes after the sizeof(a) reference, it has no effect -- I still get
the sizeof being zero.
--
Kenneth Brody
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2011-10-31 07:46 -0400 |
| Message-ID | <j8m1qh$l6e$1@dont-email.me> |
| In reply to | #12332 |
On 10/31/2011 06:35 AM, flebber wrote:
> Hi
>
> I am learning C. I am trying to sum an array with the values returned
> from a loop. Can I use the "?" operator as part of a loop; by
> experimentation I know I can't put the increment in the loop.
>
> doing ((i % 3 == 0)||(i % 5 == 0)) ? sum+=a[i] :i++ ; never actually
> finished, I think I created an infinite loop.
You can put the increment in the loop, and you did so in the code below.
What you shouldn't do is put it in a conditional part of the ternary
expression. Your loop's behavior depends only upon the value of 'i'. If,
during one pass though the loop, the value of i doesn't change, it will
go through the loop again, with the same value of i, and therefore
exactly the same behavior - which means it still won't change. Infinite
loop.
Now, with that in mind, take a look at the code above. If i has a value
which is a multiple of 3 or a multiple of 5, the value of i will not be
changed.
That's why you've got to move the i++ out of the ternary expression, as
you did in your code below.
> PS I was following the example from here
> http://www.tutorialspoint.com/ansi_c/ternary_operator_examples.htm
>
> So I have come to this this solution, I think the problem is that my
> array a[] is assigned as a one element array and since the first value
> returns false it gets 0 and exits. Is this right? ...
No, the first value does not "return false". Your code attempts to read
the first 1000 elements of a[], regardless of whether or not it actually
has 1000 elements. So what happens is that it tries to read pieces of
memory that aren't actually part of a[]. As a result, the behavior of
your program is not defined by the C standard. This is bad - very bad.
Don't do that.
> ... If it is how do i
> assign an array to have an unknown number of entries?
You can never assign an array - what you actually mean, I think, is
either "define" or "declare".
You can't define an array to have an unknown number of entries. Defining
an object requires you to give the compiler all the information it needs
to set aside storage space for the object; if you don't tell it how long
the array is, the compiler can't do that. When you declared it as int
a[], and didn't provide an actual length anywhere else in your program,
it implicitly made the length 1. But that's something you should have
known; it doesn't count as defining an array of unknown length.
What you can do is declare an array to have a number of entries that is
not known within your code, but is known SOMEWHERE ELSE. For instance,
the simplest change to your code that would allow this is to declare
extern int a[];
In some other part of your program, you must provide a definition for a
that does have a specific length:
int a[1000];
However, using global variables is seldom the best solution. All of your
variables are global, and none of them should be. A more appropriate way
to do this would be to declare a function, which takes a pointer to the
first element of the array, and length:
int three_five_sum(
int a[],
int n
){
// body of function.
}
That looks like it defines a to be an array, but one of the confusing
features of C is that the declaration of an array as a parameter to a
function is automatically converted into a declaration of a pointer to
the element type of that array. It's exactly the same as if I had
written "int *a". Just as a matter of convention, I normally declare
parameters which are pointers to the first element of an array using
array[], while I write those which are pointers to a single object as
*single_object. As far as I can tell, this convention is my own
peculiarity, and not in wide use.
> A kick in the right direction appreciated
>
> #include <stdio.h>
> int a[],i,sum=0;
>
> int main()
> {
> while(i < 1000)
> {
> ((i % 3 == 0)||(i % 5 == 0)) ? sum+=a[i] :0 ;
> i++;
> }
> printf("The sum is %d\n",sum);
> return 0;
> }
There are many good uses of the ternary operator; I use it all the time.
This isn't one of them. An expression statement containing a ternary
expression can usually be re-written using if(). Unless you're using the
result of the ternary expression, it's generally better to use the if()
version:
if( i%3 == 0 || i%5 == 0)
sum += a[i];
Of course, the whole point of your exercise was to practice the use of
the ternary operator - but you should do that with a problem for which
that operator is a reasonable thing to use. Try the following: write a
function that takes two pointer arguments, a and b, and a count. For
each value of i from 0 to count-1, it adds something to sum. However, if
i is a multiple of 3 or 5, it adds a[i] to sum; otherwise, it adds b[i]
to sum.
You've got a variable named i, which is used only inside the loop, which
must be incremented during each step of the loop. When you've got that
combination, it's generally better to write it as a for() loop rather
than a while loop:
for(int i=0; i<1000; i++)
If your code has to be compatible with C90, you'll have to break that up
into two parts:
int i;
for(i=0; i<1000; i++)
--
James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | David Thompson <dave.thompson2@verizon.net> |
|---|---|
| Date | 2011-11-21 02:39 -0500 |
| Message-ID | <66jjc7lt4hm6tb7bf45uij37091pgq55d7@4ax.com> |
| In reply to | #12341 |
On Mon, 31 Oct 2011 07:46:25 -0400, James Kuyper
<jameskuyper@verizon.net> wrote:
<snip>
> int three_five_sum(
> int a[],
> int n
> ){
> // body of function.
> }
>
> That looks like it defines a to be an array, but one of the confusing
> features of C is that the declaration of an array as a parameter to a
> function is automatically converted into a declaration of a pointer to
> the element type of that array. It's exactly the same as if I had
> written "int *a". Just as a matter of convention, I normally declare
> parameters which are pointers to the first element of an array using
> array[], while I write those which are pointers to a single object as
> *single_object. As far as I can tell, this convention is my own
> peculiarity, and not in wide use.
>
FWIW, I do the same when I get to choose the style.
Two is still far short of demonstrating wide use, though.
Further, if I can express simply enough the actual size expected or
used, I make it a comment:
void interdigitate_a_flooby (flooby * x);
void pair_items (left a [/*n*/], const right b [/*n*/], size_t n);
/* this one could be VLAs in C99 if change order */
void grommetize_blorbs (blorb b [/*g_min_blorb+tan(2pi)*/]);
/* ignore the global behind the curtain */
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.c
csiph-web