without loop printing 1 to n

K

Kohn Emil Dan

..and lateron

And how about this one? This is of course an unusual recursion, but I
think it's funny. Notice that here you are likely to be hit by a limit
imposed by the OS regarding the number of processes. Did I pass the
interview now? ;-))

Emil


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

/* Make sure you define PROG_NAME to the name of your executable.
Using argv[0] is not portable */

#define PROG_NAME "print_1_to_n.exe"

#define N 100

int main(int argc, char *argv[])
{
/* Allocate 1 digit for every 3 bits, hopefully is enough */
char buffer[sizeof(PROG_NAME) +
(sizeof(int)*CHAR_BIT + 2)/3 +
1];
int n;

switch (argc) {
case 1:
n = 0;
break;

case 2:
/* Yeah I know, atoi() is bad, real programs should
should use strtol() and check for errors*/
n = atoi(argv[1]);
if (n <= 0) {
fprintf(stderr,"Wrong arguments\n");
exit(1);
}
break;

default:
fprintf(stderr,"Wrong arguments\n");
exit(1);
}

n++;

printf("%d\n",n);

if (n>=N)
return 0;

sprintf(buffer,"%s %d",PROG_NAME,n);

system(buffer);

return 0;
}
 
K

Keith Thompson

jd said:
AAARRRGHH! And it only prints up to N-1 too. Should have been a>b.

I promise I'll never post again to clc.

No need for that. Just promise that you'll never post code without
compiling and executing it first.
 
K

Keith Thompson

Kohn Emil Dan said:
int main()

Better: int main(void)
{ [...]
return 0; /* Just to prevent a compiler warning */

No, this isn't just to prevent a compiler warning; it's to ensure that
your program returns a well-defined status to the environment. (The
"return 0;" is implicit in C99, but it doesn't hurt to have it
anyway.)
 
M

Michal Nazarewicz

Yahooooooooo said:
..and lateron

Kohn Emil Dan said:
And how about this one? This is of course an unusual recursion, but I
think it's funny. Notice that here you are likely to be hit by a limit
imposed by the OS regarding the number of processes. Did I pass the
interview now? ;-))

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

/* Make sure you define PROG_NAME to the name of your executable.
Using argv[0] is not portable */

#define PROG_NAME "print_1_to_n.exe"

#define N 100

int main(int argc, char *argv[])
{
/* Allocate 1 digit for every 3 bits, hopefully is enough */
char buffer[sizeof(PROG_NAME) +
(sizeof(int)*CHAR_BIT + 2)/3 +
1];
int n;

switch (argc) {
case 1:
n = 0;
break;

case 2:
/* Yeah I know, atoi() is bad, real programs should
should use strtol() and check for errors*/
n = atoi(argv[1]);
if (n <= 0) {
fprintf(stderr,"Wrong arguments\n");
exit(1);
}
break;

default:
fprintf(stderr,"Wrong arguments\n");
exit(1);
}

n++;

printf("%d\n",n);

if (n>=N)
return 0;

sprintf(buffer,"%s %d",PROG_NAME,n);

system(buffer);

On POSIX platforms one could even use:

#v+
sprintf(buffer, "%d", n);
execlp(PROG_NAME, argv[0], buffer, (char*)0);
#v-

And there would be no problems with the number of processes limit.
 
J

jaysome

Yahooooooooo said:


Method 1 of N:

#include <stdio.h>

int main(void)
{
puts("1 to n");
return 0;
}

Method N of N:

#include <stdio.h>
#include <assert.h>

void printrange(unsigned long low, unsigned long high)

The function name "printrange" has external linkage. As such, in order
to be strictly conforming to the C90 Standard, it must be significant
from any other external name in the first six characters. You're lucky
you didn't lose your temper and name it something like
"printfrigginrange" instead.

The latter name would, of course, collide with printf in the included
file <stdio.h>, and the result would be undefined behavior.

One convention to consider, in order to reduce the probablility of
this type of undefined behavior, is to have an underscore somwehere in
the second to sixth characters of your external name, especially if it
separates words.

As an example, consider this function prototype:

void printrange(unsigned long low, unsigned long high);

You can accomplish both of the tenets above by inserting a single
underscore after the fifth character of this function name, i.e.:

void print_range(unsigned long low, unsigned long high);

The big advantage is that someone in your audience doesn't have to
spend minutes or hours (or days or years or forever?) trying to figure
out if the author pronounced it: "PRiority INT RANGE" (the range of an
object of type int that represents a task priority); or "PRImary NT
RANGE" (The pasture where most computers still running Windows NT have
retired to); or "PRINTeR ANGE" (The angst you feel when you are
experiencing printer problems); and possibly others.

I've wasted a lot of time--no--authors have wasted a lot of my time,
by not using underscores in their names.

Have a Merry Christmas
 
R

Richard Heathfield

jaysome said:
On Fri, 22 Dec 2006 11:00:57 +0000, Richard Heathfield


The function name "printrange" has external linkage. As such, in order
to be strictly conforming to the C90 Standard, it must be significant
from any other external name in the first six characters.

And it is.
You're lucky you didn't lose your temper and name it something like
"printfrigginrange" instead.

The latter name would, of course, collide with printf in the included
file <stdio.h>, and the result would be undefined behavior.

But I didn't call it that, so I don't see what point you are failing to
make.

<snip>
 
K

Kohn Emil Dan

Kohn Emil Dan said:
int main()

Better: int main(void)
Correct.
[...]
return 0; /* Just to prevent a compiler warning */

No, this isn't just to prevent a compiler warning; it's to ensure that
your program returns a well-defined status to the environment. (The
"return 0;" is implicit in C99, but it doesn't hurt to have it
anyway.)

The point is that the code will never reach that return statement, as far
as I can see. main() will always return via the return statement
controlled by if (setjmp(...)) Therefore I think that the return statement
could have been omitted, but I placed it because I don't think that the
compiler can figure out that it will never be reached.


Emil
 
R

Richard Heathfield

Kohn Emil Dan said:
The point is that the code will never reach that return statement, as far
as I can see.

What has that to do with anything? It's a question of good programming
practice.
 
G

Guest

Richard said:
Kohn Emil Dan said:

What has that to do with anything?

Well, if the code never reaches that return statement, the program
returns a well-defined status regardless of whether that return
statement is present, so it /is/ just there to prevent a compiler
warning.
It's a question of good programming
practice.

So you support adding dead code to programs just because it would be
useful or good practice if it weren't dead code?
 
R

Richard Heathfield

Harald van D?k said:
Richard Heathfield wrote:


So you support adding dead code to programs just because it would be
useful or good practice if it weren't dead code?

I support defence in depth. When, one day, all that longjmp/setjmp nonsense
is removed and the program produces its output sensibly, it would be nice
not to have to remember to fix up main to return a proper value to its
caller.
 
G

Guest

Richard said:
Harald van D?k said:


I support defence in depth. When, one day, all that longjmp/setjmp nonsense
is removed and the program produces its output sensibly, it would be nice
not to have to remember to fix up main to return a proper value to its
caller.

How far are you willing to take that? Would you remove the final return
statement in

int main(void) {
if(...) return EXIT_SUCCESS;
else return EXIT_FAILURE;

return 0;
}

And how about this?

void func(void) { if(...) exit(0); }
int main(void) {
for(;;) func();

return 0;
}
 
R

Richard Heathfield

Harald van D?k said:
How far are you willing to take that? Would you remove the final return
statement in

int main(void) {
if(...) return EXIT_SUCCESS;
else return EXIT_FAILURE;

return 0;
}

No, I'd remove the other two returns:

int main(void)
{
int rc = EXIT_FAILURE;
if(...)
{
rc = EXIT_SUCCESS;
}

return rc;
}
And how about this?

void func(void) { if(...) exit(0); }
int main(void) {
for(;;) func();

return 0;
}

int func(void)
{
int rc = 0;
if(...)
{
rc = 1;
}
return rc;
}

int main(void)
{
while(func() == 0)
{
continue;
}

return 0;
}
 
G

Guest

Richard said:
Harald van D?k said:

No, I'd remove the other two returns:

int main(void)
{
int rc = EXIT_FAILURE;
if(...)
{
rc = EXIT_SUCCESS;
}

return rc;
}


int func(void)
{
int rc = 0;
if(...)
{
rc = 1;
}
return rc;
}

int main(void)
{
while(func() == 0)
{
continue;
}

return 0;
}

So basically, you prefer to always have main() return via a return
statement at the end of the function, possibly barring any exceptional
conditions that make this (nearly) impossible? If so, fair enough, but
that's a personal choice, and not the only way to write clear and clean
programs.
 
R

Richard Heathfield

Harald van D?k said:

So basically, you prefer to always have main() return via a return
statement at the end of the function,

Yes. Since main is defined as returning int, it seems only right and proper
to return an int from main.
 
J

jaysome

Harald van D?k said:


I support defence in depth. When, one day, all that longjmp/setjmp nonsense
is removed and the program produces its output sensibly, it would be nice
not to have to remember to fix up main to return a proper value to its
caller.

What about exit()?

#include <stdlib.h>
int main()
{
exit(0);
return 0;/*useless statement*/
}
 
R

Richard Heathfield

jaysome said:
What about exit()?

#include <stdlib.h>
int main()
{
exit(0);
return 0;/*useless statement*/
}

Close, but no banana. Here, I have removed the truly useless statement:

int main()
{
return 0;
}

:)
 
K

Kenny McCormack

Richard Heathfield said:
Close, but no banana. Here, I have removed the truly useless statement:

int main()
{
return 0;
}

I believe the well-known phrase is:

Never argue with a Richard Heathfield.
It will bring you down to its level and then beat you with experience.
 
K

Keith Thompson

Keith Thompson said:
Kohn Emil Dan said:
int main()

Better: int main(void)
{ [...]
return 0; /* Just to prevent a compiler warning */

No, this isn't just to prevent a compiler warning; it's to ensure that
your program returns a well-defined status to the environment. (The
"return 0;" is implicit in C99, but it doesn't hurt to have it
anyway.)

When I wrote the above, I didn't realize that the "return 0;" at the
end of main() is never reached.
 
A

av

On Sat, 30 Dec 2006 06:58:58 GMT, ozbear wrote:
ON TOP-POSTING
so why is so wrong read in reverse order?
more near to the top more near to now, and the part much important is
in the top so i not have not scroll all text
 

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

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,682
Members
48,796
Latest member
Greg L.

Latest Threads

Top