Return to sysprog.net home page

españolfrançaisdeutsch

C and C++

Main page

Defines

Design

Loops

Pointers

Punctuation

Strings

Stuctures

Types


SITE SERVICES
Contact Us
Search
Site Map


Home —» C and C++> —» types



C Tutorial: Types


C Types:
C is a typed language: that is, the compiler checks that all statements are consistent as far as the type of the variables is concerned. The C compiler won't let you (or will make it very hard for you) to load a numeric variable with blanks.

Fundamentally, C only has two built-in types: integers (whole numbers) and floating point numbers (those with a decimal point). These can be signed or unsigned, short or long, and all can have pointers that point to them. So you can have a 'signed short integer' or an 'unsigned char' or a 'pointer to double'.

In addition to these standard types, you can create your own user-defined types. Every structure you define is considered a type, as are any types you define using the typedef keyword, such as WORD or BYTE. Whether standard or user-defined, the compiler will require that statements only assign or compare variable with values of their own type, unless you specifically say otherwise (see casting) or the compiler has a built-in promotion scheme for that type (e.g. integer to float).

The number of bytes occupied in storage by a variable of a given type depends on the machine you're using. PC progammers have had to deal with integers doubling in size as microchips have grown more powerful. The size of types on the mainframe, however, has never changed, even for the zseries boxes. The information on this page applies only to mainframes.

Standard Types:
All standard C types are variations on integers or floating point numbers. Even characters are treated internally as unsigned integers. Floating point variables save the integer part of the number in one part of the variable, and use the remaining bits to store the decimal portion. Doubles, which are twice the size of floats, have more bits for both the integer and decimal portions. Void is used to satisfy the syntax checker when no real type is involved. For instance, functions are declared of type void when they don't return any value.

TYPE

void

char
signed char

short (or short int)
signed short
int
unsigned int
long (or long int)
unsigned long
long long
unsigned long long

float
double
long double
LENGTH

0

1
1

2
2
4
4
4
4
8
8

4
8
8
ALIGNMENT

none

byte
byte

halfword
halfword
fullword
fullword
fullword
fullword
doubleword
doubleword

fullword
doubleword
doubleword


All types, except chars, are signed by default. The boundary alignment can be forced to byte alignment by using a compiler option, such as pack in C/370 or bytealign in SAS/C.

Note that the 'long long integer' exists only on the mainframe: it was IBM's solution to the 64-bit architecture. Other platforms simply increased the length of their long integers, as they had done when they went from 16-bit to 32-bit.

Pointers:
Pointers are fullwords that contain the address of a variable. The type of variable they will point to must be specified when they're declared. Just as the compiler won't let you load blanks into an integer variable, it won't let you load the address of blanks into a pointer to integer.

Pointers are declared by following the type of variable they will point to by an asterisk and the variable name. If you list variables on one line, each pointer variable must have its own asterisk. The following line declares an integer (number), and two pointers to integer (nptr and iptr).

int *nptr, number, *iptr;

For more details on pointers to void, see the tutorial on pointers.

Typedef:
You can define your own types by using typedef. These types can either be entirely new types, such as record structures, or aliases for existing types. It's common practice for mainframe shops to use typedef to define types such as WORD or BYTE, presumably to make C more familiar to assembler programmers. Be aware that merely calling an integer WORD won't make it fullword align if you're using a noalign compiler option.

It's considered good practice to type typedefs in UPPERCASE, or at least put the first character in uppercase.

typedef char * STRING;
typedef int WORD;
typedef unsigned char BYTE;
typedef float AMOUNT;
typedef struct salesrec SalesRec, *SalesPtr;

STRING cptr;
WORD count, *iptr;
BYTE flag = 'N';
AMOUNT price = 0.0;
SalesRec order;
SalesPtr order_p;

Casting:
C will automatically convert (or promote) some variables into a different type to make them compatible in an operation. However, some conversions may surprise you, especially when they involve intermediate calculations. For automatic conversions, we recommend you to a good C manual.

The way to avoid conversion surprises, and the only way of handling user-defined types, is to cast any variables that aren't of the appropriate type. Casting means explicitly converting a variable by preceding the variable name by the desired type in parentheses.

This example explicitly converts an integer into a floating point number, because otherwise C wouldn't do the conversion to floating point until after the division. For example, if sum is 7 and count is 3 then, without an explicit cast, C would calculate 7/3=2, which it would then promote to 2.0.

int sum, count;
float average;

average = (float)sum / count;

The example below casts a pointer from character pointer to a user-defined structure pointer.

char *buffer;
struct salesrec *order_p;

order_p = (struct salesrec *)buffer;

Auto and Static:
By default, variables declared within a function are of class auto. C generates and releases auto variables each time that function is entered and exited. If you want a variable to persist after the function is exited, then place the keyword static before the variable's delaration and it won't be released when the function ends.

Variables declared outside any function are static by default.

You must declare a variable as static if you need to keep the value in a variable from function iteration to iteration, or if you intend to return the address of a variable in that function. You can also declare a constant field (one whose value won't change) as static to avoid the overhead of regenerating it every time the function is called.

static int lookuptable[100];
static float runningtotal = 0.0;
static float pi 3.14;

The word static placed before a function declaration has an entirely different meaning. A static function is only callable by other functions within the same file.

Const:
If you declare a variable to be of type const, the compiler will generate an error if you use that variable name on the lefthand side of an assignment i.e. if you try and change the value in the variable by using its name. Using const doesn't completely protect the variable. You can always get round the const by using a pointer, for instance.

const float maxpremium = 9999.99;
float *fptr = &maxpremium;

*fptr = 20000.00;


TOP OF PAGE If you think C++ is not overly complicated, just what is a protected abstract
virtual base pure virtual private
destructor?
(Tom Cargill)