So I've started learning how to program in C

Discuss whatever insanity comes to mind. Please keep it friendly and clean though.

Moderator: General Mods

Post Reply
ZH/Franky

So I've started learning how to program in C

Post by ZH/Franky »

I've been reading online guides to try and learn C. So far it's going well.
I'm only writing simple things at the moment (because I have no programming experience before starting this). Anyway I'm bored so I feel like posting something

Should be interesting if you're mega-bored.

Code: Select all

#include <stdio.h>

int main()

{
      int age;

      printf( "Please enter your age: " );
      scanf( "%d", &age );

      if ( age < 4 ) {
        printf( "Well done little one, you're able to read and write.\n" );
        printf( "Remember, girls are disgusting and will give you coodies if you touch them!\n" );
      }

      else if ( age < 12 ) {
        printf( "You are pretty young!\n" );
        printf( "Why are you wasting your time on a computer?\n" );
        printf( "Go out and play with your friends or something.\n" );
        printf( "Or play a videogame. Those are way better than going outside.\n" );
      }

      else if ( age < 17 ) {
        printf( "In a few years you'll be an adult, but you're still very young.\n" );
      }

      else if ( age < 30 ) {
        printf( "You're an adult so you've probably grown up, but you're not old yet.\n" );
        printf( "Remember, make the most out of life while you are still young.\n" );
        printf( "And for god sake, don't have kids until you're 35!\n" );
      }

      else if ( age < 60 ) {
         printf( "You're not so young anymore, but you're not a member of the elderly yet.\n" );
      }

      else if ( age < 100 ) {
         printf( "You're old.\n" );
      }

      else if ( age < 120 ) {
         printf( "You're really old!\n" );
      }

      else if ( age < 155 ) {
         printf( "You really know how to live!\n" );
      }
      
      else if ( age < 180 ) {
         printf( "You're so ancient! You must be scratching those bones of yours eh?\n" );
      }

      else {
        printf( "You should be dead by now\n" );
        printf( "I mean most people only last until maybe 110 at the most.\n" );
        printf( "How the hell have you survived this long!?\n" );
        printf( "Are you... superman?\n" );
      }
      return 0;
}
Last edited by ZH/Franky on Thu Jul 17, 2008 1:04 pm, edited 1 time in total.
Rashidi
Trooper
Posts: 515
Joined: Fri Aug 18, 2006 2:45 pm

Post by Rashidi »

well...
Edit: Since now it use indent
Last edited by Rashidi on Thu Jul 17, 2008 2:22 pm, edited 1 time in total.
Gil_Hamilton
Buzzkill Gil
Posts: 4294
Joined: Wed Jan 12, 2005 7:14 pm

Post by Gil_Hamilton »

Well...
Edit: Removed idiocy. I reversed my < and > signs.
creaothceann
Seen it all
Posts: 2302
Joined: Mon Jan 03, 2005 5:04 pm
Location: Germany
Contact:

Post by creaothceann »

Code: Select all

 is your friend.
vSNES | Delphi 10 BPLs
bsnes launcher with recent files list
ZH/Franky

Post by ZH/Franky »

creaothceann wrote:

Code: Select all

 is your friend.[/quote]
Oops, forgot about that.
grinvader
ZSNES Shake Shake Prinny
Posts: 5632
Joined: Wed Jul 28, 2004 4:15 pm
Location: PAL50, dood !

Re: So I've started learning how to program in C

Post by grinvader »

Hmm. Mind if I tweak some values a bit ?

Code: Select all

#include <stdio.h>

char *stuff[] = {
 "Well done little one, you're able to read and write.\n\
Remember, girls are disgusting and will give you cooties if you touch them!",
 "You are pretty young!\n\
Why are you wasting your time on a computer?\n\
Go out and play with your friends or something.\n\
Or play a videogame. Those are way better than going outside.",
 "In a few years you'll be an adult, but you're still very young.",
 "You're an adult so you've probably grown up, but you're not old yet.\n\
Remember, make the most out of life while you are still young.\n\
And for god sake, don't have kids until you're 35!",
 "You're not so young anymore, but you're not a member of the elderly yet.",
 "You're old.",
 "You're really old!",
 "You really know how to live!",
 "You're so ancient! You must be scratching those bones of yours eh?",
 "You should be dead by now\n\
I mean most people only last until maybe 110 at the most.\n\
How the hell have you survived this long!?\n\
Are you... superman?" };

int off[] = { 0, 1, 1, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 5,
              5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7,
              7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9 };

int main()
{
  unsigned int age = 0;

  printf("Please enter your age: ");
  scanf("%u", &age);

  age = (age > 180) ? 45 : age >> 2;
  puts(stuff[off[age]]);

  return (0);
}
17 is now 16, 30 is 32 and 155 is 156.
皆黙って俺について来い!!

Code: Select all

<jmr> bsnes has the most accurate wiki page but it takes forever to load (or something)
Pantheon: Gideon Zhi | CaitSith2 | Nach | kode54
odditude
Official tech support dood
Posts: 2118
Joined: Wed Jan 25, 2006 7:57 am

Re: So I've started learning how to program in C

Post by odditude »

grinvader wrote:Hmm. Mind if I tweak some values a bit ?

Code: Select all

...
  age = (age > 180) ? 45 : age >> 2;
  puts(stuff[off[age]]);
...
I've never used the ?, :, or >> operators... damn 10-years-ago 200-level C courses. I'm definitely out of practice.

And mmm, nested array references... please to not make pointer go b0rk b0rk b0rk :D

Edit: You might have just broken his mind with the array of char*. What am I not remembering properly about needing to null-terminate strings? Did that only apply to an actual char[] array?

Edit again because I'm not thinking yet: If you're not going to use grinmath, at the very least, switch() is your friend instead of the obscenely long if/else chain.
Why yes, my shift key *IS* broken.
ZH/Franky

Re: So I've started learning how to program in C

Post by ZH/Franky »

grinvader wrote:Hmm. Mind if I tweak some values a bit ?

Code: Select all

#include <stdio.h>

char *stuff[] = {
 "Well done little one, you're able to read and write.\n\
Remember, girls are disgusting and will give you cooties if you touch them!",
 "You are pretty young!\n\
Why are you wasting your time on a computer?\n\
Go out and play with your friends or something.\n\
Or play a videogame. Those are way better than going outside.",
 "In a few years you'll be an adult, but you're still very young.",
 "You're an adult so you've probably grown up, but you're not old yet.\n\
Remember, make the most out of life while you are still young.\n\
And for god sake, don't have kids until you're 35!",
 "You're not so young anymore, but you're not a member of the elderly yet.",
 "You're old.",
 "You're really old!",
 "You really know how to live!",
 "You're so ancient! You must be scratching those bones of yours eh?",
 "You should be dead by now\n\
I mean most people only last until maybe 110 at the most.\n\
How the hell have you survived this long!?\n\
Are you... superman?" };

int off[] = { 0, 1, 1, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 5,
              5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7,
              7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9 };

int main()
{
  unsigned int age = 0;

  printf("Please enter your age: ");
  scanf("%u", &age);

  age = (age > 180) ? 45 : age >> 2;
  puts(stuff[off[age]]);

  return (0);
}
17 is now 16, 30 is 32 and 155 is 156.
Whoa, your code is way more complex than mine. Though, at the same time it looks to be much more elegant straightforward if I actually understood it! :D
(Mind you, I'm still a newbie. Afterall, I only started trying to learn C about 24 hours before posting this comment).

I just tried your code and the actual compiled program works the same as before.

I could really learn from you. Could you comment your code though and teach me a few things please?

By the way guys, I'm using http://www.cprogramming.com/ as the guide for me learning C.
odditude
Official tech support dood
Posts: 2118
Joined: Wed Jan 25, 2006 7:57 am

Re: So I've started learning how to program in C

Post by odditude »

Over-commented code follows.

Code: Select all

#include <stdio.h>

/* Declare and initialize array of char*.  In simplest terms, each element of the array
   can be considered a string.  Elements are comma-delimited. In C, arrays are zero-indexed
   (i.e. the first element has index of 0). */
char *stuff[] = {
 "Well done little one, you're able to read and write.\n\
Remember, girls are disgusting and will give you cooties if you touch them!",
 "You are pretty young!\n\
Why are you wasting your time on a computer?\n\
Go out and play with your friends or something.\n\
Or play a videogame. Those are way better than going outside.",
 "In a few years you'll be an adult, but you're still very young.",
 "You're an adult so you've probably grown up, but you're not old yet.\n\
Remember, make the most out of life while you are still young.\n\
And for god sake, don't have kids until you're 35!",
 "You're not so young anymore, but you're not a member of the elderly yet.",
 "You're old.",
 "You're really old!",
 "You really know how to live!",
 "You're so ancient! You must be scratching those bones of yours eh?",
 "You should be dead by now\n\
I mean most people only last until maybe 110 at the most.\n\
How the hell have you survived this long!?\n\
Are you... superman?" };

/* Declare and define array of type int, containing the 46 listed elements. */
int off[] = { 0, 1, 1, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 5,
              5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7,
              7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9 };

int main()
{
  /* Declare and initialize variable of type unsigned int.  Unsigned ints range
   from 0 to 2x (size of int on your platform + 1). */
  unsigned int age = 0;

/* Prompt user for input. Note that %u (for unsigned int) is used instead of %d (int) */
  printf("Please enter your age: ");
  scanf("%u", &age);

/* Ternary comparison.  Grin is going to repurpose age as the index for an array, and is
   calculating the appropriate value.  If age > 180, then set age = 45.  Otherwise, perform
   two bitwise shifts right on the value of age.  As age is an unsigned int, this effectively
   divides it by 4 and discards the remainder. */
  age = (age > 180) ? 45 : age >> 2;

/* puts(char* argument) prints the string contained in argument.
   Our repurposed age is serving as the index to the array off, whose value is then used as
   an index to the array stuff.
   Stepped out example, if age = 5 (meaning originally 20 < age < 23):
      puts(stuff[off[5]]);
      puts(stuff[3]);
      puts("You're an adult so you've probably grown up, but you're not old yet.\n\
      Remember, make the most out of life while you are still young.\n\
      And for god sake, don't have kids until you're 35!");
*/
  puts(stuff[off[age]]);

  return (0);
}
Help any?
Last edited by odditude on Fri Jul 18, 2008 12:44 am, edited 1 time in total.
Why yes, my shift key *IS* broken.
ZH/Franky

Post by ZH/Franky »

odditude wrote:Over-commented code follows.

Code: Select all

#include <stdio.h>

/* Declare and initialize array of char*.  In simplest terms, each element of the array can be considered a string.  Elements are comma-delimited. In C, arrays are zero-indexed (i.e. the first element has index of 0). */
char *stuff[] = {
 "Well done little one, you're able to read and write.\n\
Remember, girls are disgusting and will give you cooties if you touch them!",
 "You are pretty young!\n\
Why are you wasting your time on a computer?\n\
Go out and play with your friends or something.\n\
Or play a videogame. Those are way better than going outside.",
 "In a few years you'll be an adult, but you're still very young.",
 "You're an adult so you've probably grown up, but you're not old yet.\n\
Remember, make the most out of life while you are still young.\n\
And for god sake, don't have kids until you're 35!",
 "You're not so young anymore, but you're not a member of the elderly yet.",
 "You're old.",
 "You're really old!",
 "You really know how to live!",
 "You're so ancient! You must be scratching those bones of yours eh?",
 "You should be dead by now\n\
I mean most people only last until maybe 110 at the most.\n\
How the hell have you survived this long!?\n\
Are you... superman?" };

/* Declare and define array of type int, containing the 46 listed elements. */
int off[] = { 0, 1, 1, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 5,
              5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7,
              7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9 };

int main()
{
  /* Declare and initialize variable of type unsigned int.  Unsigned ints range from 0 to 2x (size of int on your platform + 1). */
  unsigned int age = 0;

/*Self-explanitory. Prompt user for input. */
  printf("Please enter your age: ");
  scanf("%u", &age);

/* Ternary comparison.  Grin is going to repurpose age as the index for an array, and is calculating the appropriate value.  If age > 180, then set age = 45.  Otherwise, perform two bitwise shifts right on the value of age.  As age is an unsigned int, this effectively divides it by 4 and discards the remainder. */
  age = (age > 180) ? 45 : age >> 2;

/* puts(char* argument) prints the string contained in argument.
   Our repurposed age is serving as the index to the array off, whose value is then used as an index to the array stuff.  Stepped out example, if age = 5:
puts(stuff[off[5]]);
puts(stuff[3]);
puts("You're an adult so you've probably grown up, but you're not old yet.\n\
Remember, make the most out of life while you are still young.\n\
And for god sake, don't have kids until you're 35!");
*/
  puts(stuff[off[age]]);

  return (0);
}
Help any?
Well, it helps a little bit. It's not that you didn't explain it very well, I'm just a bit lost (and confused) since this is all so new to me. Maybe I should learn the foundations of C before asking someone to explain code like what grinvader gave me >_>
I do understand it a bit better now, but I've sure as hell got a long way to go.

Still, thanks for trying to help.
creaothceann
Seen it all
Posts: 2302
Joined: Mon Jan 03, 2005 5:04 pm
Location: Germany
Contact:

Post by creaothceann »

If you have the time then I suggest you start at the beginning (assembler) and work your way up. You don't have to actually write ASM programs unless it's required for understanding.

Higher-level languages such as C are meant as shortcuts - they work best if you know what each construct does internally.
vSNES | Delphi 10 BPLs
bsnes launcher with recent files list
Rashidi
Trooper
Posts: 515
Joined: Fri Aug 18, 2006 2:45 pm

Post by Rashidi »

odditude wrote:Over-commented code follows.

Code: Select all

#include <stdio.h>

/* Declare and initialize array of char*.  In simplest terms, each element of the array can be considered a string.  Elements are comma-delimited. In C, arrays are zero-indexed (i.e. the first element has index of 0). */
char *stuff[] = {
 "Well done little one, you're able to read and write.\n\
Remember, girls are disgusting and will give you cooties if you touch them!",
 "You are pretty young!\n\
Why are you wasting your time on a computer?\n\
Go out and play with your friends or something.\n\
Or play a videogame. Those are way better than going outside.",
 "In a few years you'll be an adult, but you're still very young.",
 "You're an adult so you've probably grown up, but you're not old yet.\n\
Remember, make the most out of life while you are still young.\n\
And for god sake, don't have kids until you're 35!",
 "You're not so young anymore, but you're not a member of the elderly yet.",
 "You're old.",
 "You're really old!",
 "You really know how to live!",
 "You're so ancient! You must be scratching those bones of yours eh?",
 "You should be dead by now\n\
I mean most people only last until maybe 110 at the most.\n\
How the hell have you survived this long!?\n\
Are you... superman?" };

/* Declare and define array of type int, containing the 46 listed elements. */
int off[] = { 0, 1, 1, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 5,
              5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7,
              7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9 };

int main()
{
  /* Declare and initialize variable of type unsigned int.  Unsigned ints range from 0 to 2x (size of int on your platform + 1). */
  unsigned int age = 0;

/*Self-explanitory. Prompt user for input. */
  printf("Please enter your age: ");
  scanf("%u", &age);

/* Ternary comparison.  Grin is going to repurpose age as the index for an array, and is calculating the appropriate value.  If age > 180, then set age = 45.  Otherwise, perform two bitwise shifts right on the value of age.  As age is an unsigned int, this effectively divides it by 4 and discards the remainder. */
  age = (age > 180) ? 45 : age >> 2;

/* puts(char* argument) prints the string contained in argument.
   Our repurposed age is serving as the index to the array off, whose value is then used as an index to the array stuff.  Stepped out example, if age = 5:
puts(stuff[off[5]]);
puts(stuff[3]);
puts("You're an adult so you've probably grown up, but you're not old yet.\n\
Remember, make the most out of life while you are still young.\n\
And for god sake, don't have kids until you're 35!");
*/
  puts(stuff[off[age]]);

  return (0);
}
i do however recommend more obscure apporach (and may not cross compiler compatible depend on how compiler handle the '>=' operator stuff)

Code: Select all

/* ... blahblah... nearly almost the same as grin was ...
... just rid those 'off[]' array */

int main() 
{ 
  unsigned int age = 0; 

  printf("Please enter your age: "); 
  scanf("%u", &age); 

/* WARN: this line may not cross compiler compatible*/
  age = (age>=4)+(age>=12)+(age>=17)+(age>=30)+(age>=60)+(age>=100)+(age>=120)+(age>=155)+(age>=180);

 puts(stuff[age]);
 return(0);
}
yeah i know, i could use chain of '?,:' operators instead.
odditude
Official tech support dood
Posts: 2118
Joined: Wed Jan 25, 2006 7:57 am

Post by odditude »

edit: never mind, my brain is still broken.
Why yes, my shift key *IS* broken.
blargg
Regular
Posts: 327
Joined: Thu Jun 30, 2005 1:54 pm
Location: USA
Contact:

Post by blargg »

Minor points:
- Use const: const char* stuff []. This prevents accidental modification of the strings. Before, you could accidentally do something like strcpy( stuff [1], mystr ); with const, this will become an error.

- For multi-line strings, break it into separate literals rather than using the preprocessor's \ to join lines. This allows the continuation to be indented:

Code: Select all

const char* long_string = "A\n"
    "B\n"
    "C\n";
The compiler will concatenate the strings together as if you had written "A\nB\nC\n".

- If you want to divide the int n by 4, write n / 4. If efficiency is critical and you know n is never negative, you can write (unsigned) n / 4, or the more verbose equivalent ((unsigned int) n) / 4, and let the compiler turn that into n >> 2 internally without obfuscating your code.
ZH/Franky

Post by ZH/Franky »

creaothceann wrote:If you have the time then I suggest you start at the beginning (assembler) and work your way up. You don't have to actually write ASM programs unless it's required for understanding.

Higher-level languages such as C are meant as shortcuts - they work best if you know what each construct does internally.
Oh, well I suppose that does make sense. I've been told that "higher-level" just means that the assembler code is in the compiler rather than in the source code of your program. So I suppose by "shortcut" that's what you mean.

I'll postpone learning C then, and try learning assembler.
grinvader
ZSNES Shake Shake Prinny
Posts: 5632
Joined: Wed Jul 28, 2004 4:15 pm
Location: PAL50, dood !

Post by grinvader »

Rashidi wrote:

Code: Select all

/* WARN: this line may not cross compiler compatible*/
  age = (age>=4)+(age>=12)+(age>=17)+(age>=30)+(age>=60)+(age>=100)+(age>=120)+(age>=155)+(age>=180);}
yeah i know, i could use chain of '?,:' operators instead.
I was actually trying to pull it like that, but it escaped me for some reason. Nice shot. :)

Also: who cares about platforms that don't have FALSE = 0 ?
blargg wrote:Minor points:
- Use const: const char* stuff []. This prevents accidental modification of the strings. Before, you could accidentally do something like strcpy( stuff [1], mystr ); with const, this will become an error.
Yeah, I actually made them const in my code, but didn't edit it in.
- For multi-line strings, break it into separate literals rather than using the preprocessor's \ to join lines. This allows the continuation to be indented:
Would have done it if it wasn't at indent 1.
- If you want to divide the int n by 4, write n / 4. If efficiency is critical and you know n is never negative, you can write (unsigned) n / 4, or the more verbose equivalent ((unsigned int) n) / 4, and let the compiler turn that into n >> 2 internally without obfuscating your code.
Obfuscation is the point !
I also started out with my usual variable name set (cheeses and various foodstuff), but felt it wouldn't be that funny. :p
皆黙って俺について来い!!

Code: Select all

<jmr> bsnes has the most accurate wiki page but it takes forever to load (or something)
Pantheon: Gideon Zhi | CaitSith2 | Nach | kode54
byuu

Post by byuu »

blargg wrote:- If you want to divide the int n by 4, write n / 4. If efficiency is critical and you know n is never negative, you can write (unsigned) n / 4, or the more verbose equivalent ((unsigned int) n) / 4, and let the compiler turn that into n >> 2 internally without obfuscating your code.
Convenient timing. I wanted to ask you a question about that the other day.

So, obviously, if your compiler can't optimize an unsigned divide by four to a right shift by two, then you have much bigger problems.

But how do you know when to draw the line between what all compilers will figure out, what only some will figure out, what only some will figure out with certain optimization levels set (thus making fast-build debugging unnecessarily painful), and what none will be able to figure out?

For instance, for an arithmetic coder I was writing, I had two interesting conditions:

//if hi and lo MSBs match ...
if((hi & 0x8000) == (lo & 0x8000)) -> if(!((hi ^ lo) & 0x8000))

//if second bit of hi = 0 and second bit of lo = 1 ...
if(!(hi & 0x4000) && (lo & 0x4000)) -> if(~hi & lo & 0x4000)

Yeah, your bit tricks are wearing off on me :P

Obviously, eliminating conditions are good for superscalar CPUs, and extra operations are bad for in-order execution. Since most CPUs follow the former model, we want that for the general case. The problem is that the latter is much harder for a layman to understand. But I do question if a compiler could make such an optimization on its own ... do you feel it would be better to stay with the former for clarity, even if it has a much higher potential to impact speed?

Obviously with a coder, you want speed no matter what, as they're usually designed as general-purpose libraries. Still, I don't like the idea of "let the code be slow intentionally unless you really need the speed." Speed requirements drop with time, making coding for speed bad; and yet wasting process power also sucks, especially when a laptop user might be using your app.
Gil_Hamilton
Buzzkill Gil
Posts: 4294
Joined: Wed Jan 12, 2005 7:14 pm

Post by Gil_Hamilton »

As far as LEGIBLE code goes...

Isn't this pretty much the exact situation the switch statement is for?
creaothceann
Seen it all
Posts: 2302
Joined: Mon Jan 03, 2005 5:04 pm
Location: Germany
Contact:

Post by creaothceann »

You'd have to specify ranges, like this:

Code: Select all

Case age of
      0..  3:   WriteLn(Str_000);
      4.. 11:   WriteLn(Str_004);
     12.. 16:   WriteLn(Str_012);
     17.. 29:   WriteLn(Str_017);
     30.. 59:   WriteLn(Str_030);
     60.. 99:   WriteLn(Str_060);
    100..119:   WriteLn(Str_100);
    120..154:   WriteLn(Str_120);
    155..179:   WriteLn(Str_155);
    else        WriteLn(Str_180);
End;
(age being unsigned and Str_X being the text to write)
vSNES | Delphi 10 BPLs
bsnes launcher with recent files list
Post Reply