# Thread: Tips on becoming a competent programmer

1. ## Tips on becoming a competent programmer

Hey all,
Do any of you have any tips that could help me be a better programmer? Other than the basic - 'just practice ALOT!!'

Anywhere I can get my hands dirty with uncommon sample code - simplified solutions, etc?

An example of somthing I'm looking for is

lets say I was taught to write a program using arrays to print out a binary number in twos complement - its basic, its lengthy- yet thats all I've learned regarding that in the course.

Now I come accorss this 'snazzy' little tidbit :

Code:
```// Convert the number to its two's complement equivalent.
number = ((number * -1) ^ 0xFF) + 1;```
which sure beats for loops and array manipulation.

Any help? Any other tips you've picked up along the way would help a great deal as well.
book names, favorite programming authors (deital & deital, kernegie Richie etc), sample code that knocked sense into you?

2. Sounds to me like you already know some C and have a fair bit of experience with it, and what you're looking for are helpful code tricks, rather than advice. (Just clarifying) I know a few, but not much.

#define SWITCH(a, b) {a ^= b; b ^= a; a ^= b;}
----------------------------------------
One of my favorites. Successfully switches the values of a and b without having to create a temporary variable.

if(0 == x)
----------------------------------------
This way, you'll get a compiling error if you accidentally use a = instead of a ==. Headache saver.

#ifdef MAIN_C
#define GLOBAL_VAR(t, n, v) t n = v
#define GLOBAL_VAR_UNINIT(t, n) t n
#else
#define GLOBAL_VAR(t, n, v) extern t n
#define GLOBAL_VAR_UNINIT(t, n) extern t n
#endif
----------------------------------------
I don't know if this really qualifies, but it fits rather well with my style. In my projects, I typically have several .c files, each of which will have its own .h file, which are included in all .c files. I also like to use global variables, especially with Win32 programs. With this, I only have to declare each global once, and it's automatically accessible from all my files. I'll put the actual variables in main.h, and define MAIN_C at the top. The macros automatically declare the original variable in the main.c module and place external references in all the other files. With only one delcaration for each variable, it makes it easier for me if I need to go back and change the name or type.

That's about all I can think of.

3. Originally Posted by Jaken Veina
Code:
`#define SWITCH(a, b) {a ^= b; b ^= a; a ^= b;}`
----------------------------------------
One of my favorites. Successfully switches the values of a and b without having to create a temporary variable.
But what advantage is there to not using a temporary variable?

Have a look at this thread for some ideas on why you might wish to reconsider your version of 'swap'...

4. Originally Posted by Jaken Veina
#define SWITCH(a, b) {a ^= b; b ^= a; a ^= b;}
----------------------------------------
One of my favorites. Successfully switches the values of a and b without having to create a temporary variable.
Um, except it doesn't compile for floats or doubles, and it doesn't really work for anything else.
Code:
```#define SWITCH(a, b) {a ^= b; b ^= a; a ^= b;}

int main( )
{
int i = 3;
int *a = &i;
int *b = &i;

SWITCH(*a, *b);

printf("a: %d b: %d\n",*a,*b);

return 0;
}```

5. > #define SWITCH(a, b) {a ^= b; b ^= a; a ^= b;}
Ugh, I'm gonna throw up

<blechhhhhh>

6. edit: never mind - i misread a post.'
(posted something that was already said)

put const-objects to the left hand side of equality comparision operator whenever possible.

7. Another brain-damaged suggestion, which is best fixed by turning up the warning level of your compiler rather than making your code harder to read.

What makes it easier to remember to swap the variables over rather than remembering to use == instead of =

Further, as you suggest, if both things are non-const, then your safety net is gone, and you're forced to remember the thing you should have spent effort on remembering in the first place.

> Now I come accorss this 'snazzy' little tidbit :
What happens if your integers are bigger than 8 bits (what is that 0xFF gonna do)?
What happens if your machine is already a 1's complement machine - no part of ANSI standard requires that the number representation be 2's complement.

8. @salem: in most cases it doesnt make the code harder to read.
wheter i write
Code:
`if(p = NULL) // oops`
or
Code:
`if(NULL = p) // compiler error`
is pretty much the same to read.
Code:
```void func(const String &my_str)
{
// you want to compare my_str to another string, but you accidently write:
if(my_str = "blah") // oops
}```
so i don't see that this is harder to read:
Code:
`if("blah" = my_str)...`
of course its also listet in the warnings - and i even compile with -ansi and -pedantic and eventually try to get rid of all warnings then. but sometimes if i just wanna quickly test something, i don't want to bother reading through the warnings (which are harmless for testing purposes in 90% of the time (i mean if you just quickly test something it will still work correctly despite tons of warnings).

edit:
>> Further, as you suggest, if both things are non-const, then your safety net is gone, and you're forced to remember the thing you should have spent effort on remembering in the first place.

in that case only warnings help. but i prefer errors over warnings.

edit2: also i rarely come accross situations where i compare 2 non-const objects.
(but i make excessive use of const so that might be a reason for it )

edit3: oh, c-board... no references... well whatever...

9. >in most cases it doesnt make the code harder to read.
Salem's point is that the convention only applies when special conditions are met (ie. one of the operands cannot be assigned to). Otherwise, the convention is pointless. Also, when you're used to a convention it's easy to read, but most programmers think in the other direction: "if the thing I want to test is equal to the thing I want to test for" rather than "if the thing I want to test for is equal to the thing I want to test". Reversing a common logical test can be confusing even if the result is identical.

However, this remains a style issue. As long as the convention is consistent, it's not difficult to read code which uses it.

>if(my_arg = "blah") // oops
If your snippet weren't off-topic for the C forum, the example would be fundamentally flawed anyway because you don't compare strings in C with the == operator.

10. >> If your snippet weren't off-topic for the C forum,
sry, that happens to me again and again. maybe one day i'll manage not to post c++ code in the c forum

11. >maybe one day i'll manage not to post c++ code in the c forum
I always check the forum I'm posting in before posting code because I have that tendency as well.

12. Originally Posted by trickae2
Do any of you have any tips that could help me be a better programmer? Other than the basic - 'just practice ALOT!!'
Focus on understanding data types.

Originally Posted by trickae2
Anywhere I can get my hands dirty with uncommon sample code - simplified solutions, etc?
Learn to separate the wheat from the chaff on these little 'tricks'. As you've seen, many of these are outdated or bad practice.

In fact, learn to avoid a lot of tricks and write simple, straightforward, easy-to-understand-and-maintain code.

13. Originally Posted by Dave_Sinkula
Focus on understanding data types.

Learn to separate the wheat from the chaff on these little 'tricks'. As you've seen, many of these are outdated or bad practice.

In fact, learn to avoid a lot of tricks and write simple, straightforward, easy-to-understand-and-maintain code.

Thanks for the advice. Alright then besides the tricks - how do I become as competent as you guys at programming. I'm not in software engineering or anything, but I did an introductory C course that was offered in my EE program. I didn't think the course was rigorous enough as we only covered
- basics (arrays, string manipulation, loops)
- mips code

I understand there's a wealth of knowledge to expand on with just that - but we lightly touched on it. Other university's have game designs as assignments right after they covered loops - while at ******* university we just covered printing out ascii triangles in different orders.

should I look towards advanced C programming books?

14. I have a trick for you.

Allways return something from any function you make. And Allways handle that return value. After you've done it, youre probably qualified to decide by your own when not to return anything...

And then go exploring all new things you find interesting. One of the most important attributes of "good" programmer is knowledge and the know-how. The more you know, the better you know how HARD it is... but the more you know HOW TO the easier it becomes.

Or something like that. I aint good with words in english, but I hope my point is there somewhere.

15. Originally Posted by Rennor
I have a trick for you.

Allways return something from any function you make. And Allways handle that return value. After you've done it, youre probably qualified to decide by your own when not to return anything...
@ The OP...

Error handling is a fairly big deal in making robust programs. Because writing error handling code adds a considerable amount of work, it might seem easier to just get the code working, and then get the error handling happening after it all works. The path of least resistance might not be the best path though - it might be wiser to write the code initially with the error handling in mind, and implement it as you go.

With regards to return values from functions - if you try to keep the maxim A function should ideally do one thing, and do it well, then you should find yourself returning error codes from a given function, letting the caller deal with the mess. Rather than adding error code to a given function, and thereby making your function potentially do two things (or more), let the caller do the work.

You should get into the habit of adding lots (by 'lots' I mean the amount necessary) of error handling code as you write. Never make assumptions that something will just work. Plan on things not working, so that if they break, you have something in place to look after it.