C Language / Lesson 1 Next Page

Find in this page : Data Types Constants Scalars & aggregates

A first program in C

Here's a simple program that will help us introduce the basic syntax rules of a C program

This program here
• is complete
• is error free
• has no dependencies on other modules
  (apart from the standard C libraries)
• runs successfully
Let's now describe what we see inside this small piece of code :
Case sensitivity
To begin :
  The code is case sensitive : capital (upper-case) letters cannot be interchanged with their corresponding small (lower-case) letter . This means that if I wrote VOID instead of void or Printf instead of printf , this would be an error. It is recommended that lower-case is used for variable names and function names for simplicity. Later we will see cases where traditionally capital letters (upper-case) are used.
Comments
  // My first program in the above sample program is a comment line There are two different ways to add comments to C code :
i. The text following two slashes // in one line is ignored by the compiler (this means that the two slashes do not have to be at the beginning of the line
ii.The other way to add comments to the source code is enclose them inside /* and */
Example:
  printf("Hello"); /* this is also a comment */ Note: The latter can be used for multi-line comments, it is therefore recommended to use the // for single line comments so that if later needed these can be commended out with a multi-line comment
Include files
  An include file has the extension .h because it is also called a "header file" . It is a text file (it can be edited with any editor like Notepad). So an include file is not used during linkage like machine code modules and libraries (.lib) or execution of a program line dynamic linked libraries (.dll). Instead it is used as source code during compilation of the program. The #include statement is a pre-processor directive like all statements in C beginning with a #. When a program is compiled every time it "sees" an #include statement it loads the file mentioned in the statement and treats it as if it was part of the program. It is easily understood that the purpose of include files is to avoid repeating common pieces of code frequently used by typing it again and again in more than one programs. Instead we write the code in an include file and whenever we need it in our program we "include" it. Such code is usually the function prototypes explained in the next paragraph.
Functions
  Before introducing the functions that appear in the given code, here is a general discussion on functions : A function is a named set of program statements that can be executed (called) from many different points in a program. A function based on its design, can accept 0 , 1 or more arguments (passing parameters is another equally correct term for arguments) but when its execution is completed it can return maximum one result (return value).
Examples :
1. the statement
x = foo(a,b,c) ;
executes the function foo which was designed to accept three arguments and the return value when the execution is completed is assigned to variable x .
2. the statement reset() ; executes the function reset without passing any arguments and no result is returned.
  Functions is a term used in almost all programming languages but unfortunately it does not always have the same meaning. Other keywords like "Procedure", "Command", "Subroutine" etc. are combined with the keyword "function" to distinguish between reentrant code that has different behaviours. Some languages for instance use a different term for functions that do not return a result.
In Visual Basic for example there are two types of procedures : Functions returning a result and Subroutines not returning anything.
  In C language things are a little easier :
  • Every program statement is in a function (see below)
• Unlike other languages it is called a function regardless of whether it returns or not a result – of course as in all languages a function can return no result or only one result value.
• In C every name that is directly followed by a pair of parentheses (empty or not) is the name of a function. For instance if someone asks you what is the meaning of blabla() found in a program, for one thing you can be sure : blabla is a function.
Only exception to this rule is the operator sizeof( . . . ) which will be explained later.

 

Data Types

G e n e r a l

C type declarations have the general form:

[class][type] declarator [=initializer] [, declarator [=initializer] ...]

All variables must be declared before they can be used.

A variable name (identifier) can be modified with :
- a trailing * to signify a pointer
- [N] where N is a positive integer to signify an aggregate (array)
A declaration of an identifier may also be followed by (...) to signify function returning data type .

 

Binary Integer Types

char Character Data Type

The char type declares an object to be of "plain" binary type which is large enough to store an ASCII character. In ASCII character set the size of a character code is eight bits (1 Byte). A char may contain any 8-bit representation, not just the ASCII characters. The data type char is signed by default and therefore the range of values of a char is -128 to 127, inclusive. Usually however we prefer to use chars as unsigned integers. This can be done using the modifier unsigned (see below).
Unsigned characters are >=0 and therefore give a range from 0 to 255 (a total of 256=2^ 8 different values)

In Microsoft C "plain" chars may be defined by default as unsigned using the /J compile-time switch.

Conclusion #1: sizeof(char) is 1.
Conclusion #2: the range of an unsigned char value is 0 to 255.

Note : The reserved word sizeof(... ) is called 'a pre-processor operator' and is a syntax exception because it looks like a function i.e it has a name like any identifier and is followed by parentheses. sizeof(...) returns the allocated size in bytes by a defined variable or of a known data type as in the above example

Examples

char value, birth_date[6];

char action_code = 12;

char selected_lang = 'G';

char *pointer_to_char;

 

Note : A character constant may be assigned to a character variable as well as shown in the above example ( 'G' ). It is very important to make clear that a character constant in C is totally different from a string constant.

A character constant represents the value of one character which is written enclosed in single quotes as in 'G'

A string constant represents an aggregate (a group) of characters and is always written with the characters enclosed in double quotes . Example "Please press a key"

 

int Integer Data Type

The int type declares an object to be of "plain" integral type. The size (and representation) of an int object is implementation-defined.

An int is the same or greater in size than a short int, and the same or less than the size of a long int (see below).
Normally the size of a short int is 2 bytes.

In most DOS/Windows C compilers, an int is short int and thus the size of an int object is two bytes and ints are signed. ( That is, int is equivalent to signed short).

The range of values of a 2-byte signed int is -32768 to 32767 inclusive.

Examples

int rec_count = 0;

int bit_pattern = 0X7FFF;

int counters[6], *ip;

Numeric constants

These are the basic rules for numeric constant notation in C

The 1st character of a constant is always a digit. Any identifier beginning with a character other than a digit is a label or the name of a variable or function  
If the 1st digit is not a 0 , then the constant is a decimal constant Example : 5467
If the 1st digit is = 0 , then the constant is an octal constant Example : 033

If the two leading characters are 0x , then the constant is a hex constant
(note : the x may be upper or lower case)

Example : 0xEFFF

 

short Short Integer Data Type

The keyword short may be applied to the int type. The short int type declares an object to be of type int and size 16-bits (2 bytes). short int must be the same or less in size than an int.

The keyword "unsigned" may be used as a prefix to short int, to identify the short integer as being unsigned.

If short is used without the keyword int, the int is assumed.

Examples

short int value = 6;

short x,y,z;

short int counters[6];

short *ip;

Conclusion : sizeof(short) is 2.

long Long Integer Data Type

The keyword long applied to the int type, declares an object to be of integer binary type. The size of a long int object is four bytes and its range of values is -2147483648 to 2147483647, inclusive.

A long int is guaranteed to be the same or greater in size than an int. However, usually the int type is the same as short.
Therefore it is suggested that declarations of long ints are done with the type long

Long constants

An integral constant with the suffix L (or l) is interpreted as a long int constant, as is any integral constant that is too big to be represented in an int.

Examples

long int value = 6L;
long equip_info = 0X00400010L;
long counters[6];
long *lptr;

Type Modifiers: Keywords that Modify Data Types

Type modifiers are keywords that can be used to prefix a data type in a declaration. They modify the type by changing its storage size (e.g. short and long) or the way in which it is interpreted (e.g. signed and unsigned.) etc.

Examples

unsigned long ul;
signed short int ssi;

 

Floating pointTypes

All type presented above are binary integer types that is they don't accept real numbers as values (containing a fractional part)

Following are the types that do this job. However it must be mentioned that there is nothing really special about floating point types in C : They are treated as in most languages (Pascal, Basic etc) and they are mainly used for numeric figures which must support the relevant characteristics in order to be involved in math calulations. That is why an emphasis must be given in C to the binary integer type where C does a lot more than any other language and in more optimized ways, starting from text processing and parsing to bit-wise manipulations.

float Single precision floating point Data Type

This type declares 4-byte floating point variables. It must be mentioned that unlike integer data types, ranges is not the important issue here since due to the presence of the exponent part of floating point numbers (see note below) the range is usally wider that required. What matters here is how may significant digits can a float variable hold. The answer is that single precision numbers can have approximately 6 significant digits. For example number 12345678 has 8 significant digits and doesn't therefore fit in a single precision variable, whereas number 123000000 although bigger than the former has only 3 significant digits and does fit in a single precision variable.

Examples of float variable definitions
float salary ;
float max_debit= 1260.0 ; // floating point constant must have a decimal point
float million = 1.0e6 ; // the e in the constant value indicates the exponent of 10

double Double precision floating point Data Type

This type is just another floating point type with all the features of the one previouly described. However it is bigger 8-byte and thus it can declare variable which will contain values with more significant digits (approximately 15 ).

 

Scalars and aggregates

G e n e r a l

The word 'scalar' was borrowed from Physics where a scalar is a measure with no dimension or direction i.e. it doesn't have a direction - it is not a vector. The same definition can be used in C language with the difference that the words dimension and direction are used with a different meaning.
An array is a vector in the sence that it doesn't have only one measure(one value). For example the area of a surface may be expressed with two figures to denote the width and length from which the area is calculated. This could be written in some other language as

area = Array (12.3 , 3.26)

In C, arrays are called aggregates. An aggregate is therefore a variable with multiple values. It can also have multiple dimensions. A variable containing only one value is not an aggregate but it is a scalar. Previously in this page definitions like these

short int myvalue = 6;

short int counters[6];

defined scalars and aggregates. Variable myvalue is a scalar and variable counters is an aggregate.

How do I know? the definition of counters has a pair of square brackets following the name of the variable.

What about multidimension aggregates ? The above variable counters is a one dimension aggregate: It contains only one row which can contain 6 values. Let's see the syntax for multi-dimension definitions in C

char grade[12][26] ;
int y[100][300][140] ;

The above are definitions of a 2D character aggregate and a 3D integer aggreagate. In the example of the grade variable , this contains 12 rows of 26 elements each.

The 0 base headache

In C the first element of an aggregate for example x[12] is x[0]. Obviously the last element is x[11]. One must be very careful because these subfixes confuse the newcomer. And the situation becomes more desperate when we learn that a string is stored in a character aggregate since there is no data type in C called string or so.
And also that a string stored in a char aggregate is null terminated with the Null character which is written in C like this: '\0' (read the note below ).

char message[6]= "Hello" ;

is stored in memory like this
H
e
l
l
o
\0

This means that
To store the 5 byte string value "Hello" we must allocate 6 bytes
The Null character is implied to be there in string literal definitions like "Hello"
The last (printable) character of the 6 byte string message[ ] is in message[4]

Note : \0 is one character and is written like this to distiguish from the printable 0 which as you can see in the ASCII table corresponds to the value 48 (30 hex) and not to 0 .

Next Page or Sample Program