C/C++ Review

Introduction

This page will focus on reviewing important C/C++ concepts needed for DS development. If you don't know C/C++ (which you must), the recommended tutorial to follow is http://www.cplusplus.com/doc/tutorial/ because it is very well written and structured with lots of useful examples to the C standard libraries (but don't use the C++ standard library in Nintendo DS projects, it's too heavy and memory hungry!). Although it is a C++ tutorial, it mostly applies to programming in plain C as well.

NOTE: The standard PAlib project main file is called main.c. This DOESN'T allow you to use C++. If you want to use C++ renaming main.c to main.cpp does the trick, idem for other source code files.

Note

If you're new to programming in C/C++, you should find it beneficial to spend at least a week getting to grips with the basics before moving on to learning PAlib.

Asking for help (important!)

You are always welcome to ask for help on the forums, but keep in mind that you may simply be pointed to a specific link that refers to the topics of interest to you.

  • ”… doesn't work” is quite vague. State your intention, expected result and actual result.
  • When asking for help, always include error messages where applicable. If possible, don't type, but copy-paste it in its entirety.
  • Always use [code] … [/code] tags when including code samples or error messages.
  • If you plan on attaching a file or code sample of reasonable size, indented code is prefereable (at least to some extent. Always indent your code.)
  • Try searching the forums (and Google, etc. for non-PAlib specific questions) before asking for help.
  • If a file(s) being attached is less than 512 KB in total, consider attaching it instead of linking to external websites. You can attach files by clicking on 'Additional Options' below the reply text-box.

Tips

Operators

Operators are programming language elements that tell a given language how to combine, compare or modify the values of an expression. An expression is a statement in which operators operate on values (e.g., 3 + 4 —the + operator is operating on the values 3 and 4).

Arithmetic Operators

(add, subtract, multiply, divide, and perform other arithmetic operations)


  + addition
  ++ increment (add 1)
  - when placed between 2 numbers, performs subtraction
  -- decrement (subtract 1)
  * multiply
  / divide
  >> bit shift right
  << bit shift left
  ( ) define precedence (operations within parentheses happen first)
  % modulus (computes the remainder of dividing two numbers)
  - when placed before a number, reverses the sign of a number (negation)

Comparison Operators

(compare two values and determine if the comparison is TRUE or FALSE)


  < is less than
  <= is less than or equal to
  == is equal to
  >= is greater than or equal to
  > is greater than
  != is not equal to

Logical Operators

(also known as “Boolean” Operators) (compare conditions and determine whether one condition exists, all conditions exists, or the conditions are different)


  ! (not)
  && (and)
  || (or)

Assignment Operators

(assign the value on the right to the var. or other container on the left)


  = simple assignment
  += add two numbers (or concatenate two strings) and assign the result to the var. on the left
  -= subtract the value on the right from that on the left and assign the result to the var. on left
  *= multiply the two values and assign the result to the var. on left
  /= divide the left value by the right value and assign result to var. on left
  %= compute the modulus of two numbers and assign result to var. on left
  >>= bit shift the left value by the right value and assign the result to the left value (right)
  <<= bit shift the left value by the right value and assign the result to the left value (left)

Ternary Operator

This is a special type of “operator” that allows you to use if statements in a function call.

comparison ? true_actions : false_actions;

An example is:

return (x < 1) ? 0 : x;

Types

Floating point operations are much more CPU intensive than integer operations on the NDS because of the lack of a FPU (floating point unit), so seek alternative methods where applicable, either integers or fixed point math.

Integral Types

Type Size Unsigned Signed AKA
char 8 bits 0 → 255 -128 → 127 u8,s8
short 16 bits 0 → 65 535 -32 768 → 32 767 u16,s16
long 32 bits 0 → 4 294 967 295 -2 147 483 648 → 2 147 483 647 u32,s32

int is special and is typically dependent upon the architecture; i.e 16 bits on systems with 16 bit CPUs and 32 bit on those with 32 bit CPUs(NDS). If an absolute range is required, for portability reasons, use either short or long.

char is also special and is typically dependent upon the compiler; It may be signed or unsigned, so care must be taken when using them. If in doubt over which integral type to use, consider using int. libnds (and consequently PAlib) provides clearer aliases for these types, e.g u8 for an unsigned 8bit integer and s32 for a signed 32bit integer, where the format is [signedness prefix, s or u][followed by the number of bits].

Modulo (%)

In C/C++, the Modulo_operation(%) operation does not wrap-around as you'd expect on negative values. e.g

-2 % 10

does not result in 8, but -2; To yield the expected result, you must add 10(the divisor) to the result.

if (lv < 0)
    result = (lv % rv) + rv;
else
    result = (lv % rv);

where lv(the dividend) is -2 and rv(the divisor) is 10.

Bitshifts (<< or >>)

Bit shift is an alternative to multiplication and division, which are CPU intensive. Basically this is how it works… the computer interprets numbers in 1s and 0s. Each number as we see it is a series of 1s and 0s in a row. This is called the binary system. For example, 1 in binary is… well… 0001; 2 is 0010; 4 is 0100; and 5 is 0101. As you can see, the number's value is determined by the place it holds and the value of each place is equal to the previous one multiplied by 2.

table of comparison
0 0 0 0 0 0 0 0 0 0
51225612864 32 16 8 4 2 1

You can see that, as you go left, each value is the previous value multiplied by 2. Thus 0001 is 1 and 0010 is 2. You can also have numbers like 0011 which is 3 ( 2 + 1 ) and 1010 which is 10 ( 8 + 2 ).

Now to the main point. Bit shifting is a trick to multiply or divide without multiplying or dividing. For example, to bit shift 0010 left by a factor of two is to move its '1' left two places to 1000 or 8. This is equivalent to multiplying by 4. For 0110 (6) bit shifted left 1, it will become 1100 (12). It works the other way too. 1010 (10) bit shifted right 1 is 0101 (5). This is where it is useful to us PAlibers. Division is CPU intensive, thus to have an alternative for division (bit shifting) is to be able to have really small increments for smoother sprite movements. To see how you would implement this in actual code, go here and keep in mind that the « and » are bit shifts.

Please also note it works similar way as with multiplying or dividing by 10, 100, 1000 etc. in your every-day life - you just move the comma or add/remove zeroes. The only difference is it uses powers of two instead of ones of ten.

Eg. 256»8 = 1

int vs char and C string functions

As noted above, char is not always signed, therefore, if you are planning to use the return value to indicate both error and result, it may be better to use int over char to account for any possible over/underflow.

Timer

PA_WaitForVBL() is a common way of creating a timer and this is how to calculate it:

Conversion:

VBLs per second = 60 approx

time = 180 (change it to lengthen or shorten the timer. We will loop this many times in our code. For now we'll make it 180 times.)

ts = time in seconds

(seconds to VBLs) time = ts * vbls per second → time = 3 * 60 → time = 180 VBLs

(VBLs to seconds) ts = time / vbls per second → ts = 180 / 60 → ts = 3 seconds

Example code:

int time = 180;
int i;
for(i = 0; i < time; i ++) // waits three seconds roughly.
	PA_WaitForVBL();

Coding style

A consistent coding style (and structure) yields more readable and consequently less buggy code, which may be beneficial to you later or when help is needed. (see External Links)

External Links

Recommended C/C++ tutorial
Frequently asked questions in C - mostly advanced
Frequently asked questions in C++ - mostly advanced
Fixed Point Math – the NDS has no dedicated floating point unit
C++ reference - applies to C as well, with good examples
C reference – less examples, but may be better for function documentation
Linux/Torvalds CodingStyle – C
Google StyleGuide – C++


 
cpptut.txt · Last modified: 2010/01/06 18:45 (external edit)
 
Except where otherwise noted, content on this wiki is licensed under the following license:CC Attribution-Noncommercial-Share Alike 3.0 Unported
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki