Difference between revisions of "C language"

From ScienceZero
Jump to: navigation, search
(#define)
Line 15: Line 15:
 
*Crashes when you try to access memory
 
*Crashes when you try to access memory
  
== Declarations ==
+
== Preprocessor ==
 +
Preprocessor commands are identified by the # at the beginning of the line.
 
=== #define ===
 
=== #define ===
<nowiki>#define</nowiki> is a preprocessor command, identified by the # at the beginning of the line. It tells the preprocessor to open a file the file and insert it at the pointof the commansd at compile time. If the file name is surrounded by angle brackets < > the compiler will search for the file in a region designated by the operating system as SET INCLUDE. Had the file name been delimited by double quotes, the compiler would have searched only the default directory for the file.
 
  
 +
=== #include <filename> ===
 +
<nowiki>#define</nowiki> tells the preprocessor to open a file the file and insert it at the pointof the commansd at compile time. If the file name is surrounded by angle brackets < > the compiler will search for the file in a region designated by the operating system as SET INCLUDE. Had the file name been delimited by double quotes, the compiler would have searched only the default directory for the file.
 +
 +
== Declarations ==
 
=== volatile ===
 
=== volatile ===
 
The volatile keyword tells the compiler that the following object is subject to sudden change in a way that is not described in the source code. For example a RS-232 data register that receive data from the outside. Volatile forces the compiler to generate the code that access the memory location each time instead of cache it in a register. Can be applied to any declaration.
 
The volatile keyword tells the compiler that the following object is subject to sudden change in a way that is not described in the source code. For example a RS-232 data register that receive data from the outside. Volatile forces the compiler to generate the code that access the memory location each time instead of cache it in a register. Can be applied to any declaration.

Revision as of 02:01, 27 January 2011

There are countless ways of tripping yourself up using the C language. The compiler will happily accept what you write, no matter how stupid the mistake is. This document points out some of the most common things that you need to know.

The stack

The stack has a limited space allocated to it, all your variables and temporary storage used by function calls are stored on the stack. When the limited space runs out you will not get a warning, your program will simply fail. You need to know how to adjust the size of the stack so it fits the requirements of your program.

Symptoms:

  • The program counter seems to jump around at random
  • Corrupted variables and data
  • Interrupt functions fail

The heap

The heap is a data structure that is used to keep track of free and allocated memory. If the heap is not initialized any attempts at reserving memory with malloc will fail.

Symptoms:

  • Crashes when you try to access memory

Preprocessor

Preprocessor commands are identified by the # at the beginning of the line.

#define

#include <filename>

#define tells the preprocessor to open a file the file and insert it at the pointof the commansd at compile time. If the file name is surrounded by angle brackets < > the compiler will search for the file in a region designated by the operating system as SET INCLUDE. Had the file name been delimited by double quotes, the compiler would have searched only the default directory for the file.

Declarations

volatile

The volatile keyword tells the compiler that the following object is subject to sudden change in a way that is not described in the source code. For example a RS-232 data register that receive data from the outside. Volatile forces the compiler to generate the code that access the memory location each time instead of cache it in a register. Can be applied to any declaration.

Symptoms of missing volatile statements:

  • Code fails when you enable compiler optimizations
  • Code fails when interrupts or DMA/Hardware peripherials are enabled
I2C1_CR1 (*((volatile unsigned long *) 0x40005400))

extern

The extern keyword indicates that the actual storage and initial value of a variable, or body of a function, is defined elsewhere, usually in a separate source code module.

extern int counter;

static

The static keyword tells the compiler to preserve the last value of the variable between successive calls to that function.

static int counter;

const

Read only. Can be applied to any declaration.

const volatile unsigned long int base_address = 0xFFFF;

register

Tells the compiler to force a variable to say in a register for improved performance. The compiler can ignore the keyword and use some other form of optimisation.

register unsigned int i;

Pointers

Pointer subtraction

The following statements apply to all pointers in C. They also apply to pointers, other than pointers to members, in C++:

  • When one pointer is subtracted from another, the difference is obtained as if by the expression: ((int)a - (int)b) / (int)sizeof(type pointed to)
  • If the pointers point to objects whose size is one, two, or four bytes, the natural alignment of the object ensures that the division is exact, provided the objects are not packed.
  • For packed or longer types, such as double and struct, both pointers must point to elements of the same array.

Control flow

for

  • for (initialise; test; modify) { statement } ;

do

do { statement } while (expression) ;

while

while (expression) { statement } ;

Switch

switch(exspression)
{
	case constant-expression :
	//code
	break;
	default: // This is taken if no case statements match.
}

break

Pass control to the statement after the loop

continue

Pass control to the start of the loop

If

  • if (expression) { statement }
  • if (expression) { statement } else { statement }
  • if (expression) { statement } else if (expression) else { statement }

? (ternary condition)

Is this wise? It seems like more pain and very little gain...

  • (expression1) ? (expression2) : (expression3)
z = (a > b) ? a : b;
   is the same as
if (a > b) z = a; else z = b;

goto

  • goto label

Artithmetic and logical operations

Bitwise logical operations

  • & AND
  • | OR
  • ^ EOR
  • ~ NOT

Shifts (ARM compilers)

  • Right shifts (>>) on signed quantities are arithmetic (implementation defined).
  • Any quantity that specifies the amount of a shift is treated as an unsigned 8-bit value.
  • Any value to be shifted is treated as a 32-bit value.
  • Left shifts (<<) of more than 31 give a result of zero.
  • Right shifts of more than 31 give a result of zero from a shift of an unsigned value or positive signed value. They yield –1 from a shift of a negative signed value.


  • >> - Right shift
  • << - Left shift
  • Rotate
    • Rotate right (ROR) for unsigned int can be implemented as r0 = ((r0 >> n) | (r0 << ((sizeof(unsigned int) * 8) - n)));
    • Rotate left (ROL) for unsigned int can be implemented as r0 = ((r0 << n) | (r0 >> ((sizeof(unsigned int) * 8) - n)));

&& || ==

!= > < >= <=

+= -=

  • =

/= >>= <<=

Type specifiers

Data types (ARM C and C++)

  • char 8 bits (signed or unsigned is implementation defines so always specify)
  • short 16 bits
  • int 32 bits
  • long 32 bits
  • long long 64 bits (The low word of a long long is at the low address in little-endian mode, and at the high address in big-endian mode.)
  • float 32 bits
  • double 64 bits
  • long double 64 bits
  • All pointers 32 bits
  • bool (C++ only) 32 bits

Memory alignement in bits is word length or 32 whichever is smallest

Other

  • void
  • signed
  • unsigned

type casting subroutines void return global vs local

& (unsigned int *)

arrays multiple dimensions array pointers, 1d, 2d string, terminating character /n /r /t escape characters vs ""

character and on what type of lines is belongs on


include files "file" <file> .c .h included libraries