Sunteți pe pagina 1din 40

C Programming Language

Lecture 2

C Programming Language
Lecture content
Data representation
Types
Conversions
Q&A

C Programming Language - Lecture


2

Data representation
All data objects in C except bit fields are represented at
run time in the computer's memory in an integral
number of abstract storage units
Each storage unit is made up of some fixed number of
bits, each of which can assume either of two values,
denoted 0 and 1
Each storage unit must be uniquely addressable and
is the same size as type char
The number of bits in a storage unit is
implementation-defined in C, but it must be large
enough to hold every character in the basic character set
The C Standard also calls storage units bytes: a storage
unit consisting of exactly eight bits
The size of a data object is the number of storage
units occupied by that data object
C Programming Language - Lecture
2

Data representation
i = 305419896 = 0x12345678
(4 bytes)

The addressing model most


natural for C is one in which
each character (byte) in the
computer's memory can be
individually addressed
Computers using this model
are called byteaddressable computers
Byte order establishes
which byte of storage is
considered to be the "first"
one in a larger piece:

Little endian
Memory
Memory
addresses
locations
0x1200
0x78
0x1201
0x56
0x1202
0x34
0x1203
0x12

Big endianMemory
"little-endian"
Memory
architectures: the address of
addresses
locations
a 32-bit integer is also the
address of the low-order byte
0x1200
0x12
of the integer
0x1201
0x34
"big-endian" architectures
0x1202
0x56
the address of a 32-bit
integer is the address of the
0x1203
0x78
high-order byte of the
integer
C Programming Language - Lecture
2

Data representation

Some computers allow data


i = 305419896 = 0x12345678
objects to reside in storage at any
(4 bytes)
address regardless of the data's
Aligned
on word
type
MemoryboundaryMemory
Others impose alignment
addresses
locations
restrictions on certain data
0x1200
0x78
types, requiring that objects of
those types occupy only certain
0x1201
0x56
addresses
0x1202
0x34
It is not unusual for a byteaddressed computer, for example,
0x1203
0x12
to require that 32-bit (4-byte)
integers be located on addresses
Not aligned on word
that are a multiple of four
MemoryboundaryMemory
Failing to obey the alignment
addresses
locations
restrictions can result in either a
0x1201
0x78
run-time error or unexpected
program behavior
0x1202
0x56
The C programmer is not normally
0x1203
0x34
aware of alignment restrictions
because the compiler takes care
0x1204
0x12
to place data on the appropriate
address boundaries C Programming Language - Lecture
5
2

Types
A type is a set of values and a set of
operations on those values
A variable or expression "has type T" when its
values are constrained to the domain of T
The types of variables are established by the
variable's declaration
The types of expressions are given by the
definitions of the expression operators
The C language provides a large number of
built-in types, including integers of several
kinds, floating-point numbers, pointers,
enumerations, arrays, structures, unions, and
functions
C Programming Language - Lecture
2

Types
C Types

Type categories

short, int, long, long long


(signed and unsigned)
char (signed and
unsigned)
_Bool

Integral types
C99

enum
float, double, long double
float _Complex
double _Complex
long double
_Complex
float _Imaginary
double _Imaginary
long double
_Imaginary
T*
T []
struct {}
union {}
T ()

C99

Arithmetic types

Scalar types

Floating point
types

Pointer types
Array types
Structure types

Aggregate types

Union types

C Programming Language - Lecture


Function types
2

Types

Integer types in C are used to represent:


signed or unsigned integer values, for which the usual arithmetic and
relational operations are provided
bit vectors, with the operations "not," "and," "or," "exclusive or," and left
and right shifts
boolean values, for which zero is considered "false" and all nonzero
values are considered "true," with the integer 1 being the canonical
"true" value
characters, which are represented by their integer encoding on the
computer
enumeration types are integral, or integer-like types

Signed types specifiers:

short or short int or signed short or signed short int


int or signed int or signed
long or long int or signed long or signed long int
long long or long long int or signed long long or signed long
long int

Unsigned type specifiers:

unsigned
unsigned
unsigned
unsigned

short intopt
intopt
long intopt
long long intopt
C Programming Language - Lecture
2

EXAMPLES
short i, j;
long int k;
unsigned int m;
unsigned n;
8

Types

Standard C specifies the minimum


precision for most integer types:

Type char must be at least 8 bits wide


type short must be at least 16 bits wide,
type long must be at least 32 bits wide
type long long must be at least 64 bits
wide.

Standard C requires that: int not be


shorter than short int and long int not
be shorter than int
The actual ranges of the integer types
are recorded in limits.h; C99 adds
stdint.h for additional integer types
By far the most common binary
encoding technique for integers is
called twos-complement notation, in
which:
a signed integer represented with n bits will
have a range from -2 n-1 through 2n-1-1
an unsigned integer represented with n bits
will have a range from 0 through 2 n-1

Integer types on a 16-bit machine


Type
short int
unsigned short
int
int
unsigned int

Smallest
value

Largest
Value

-32768

32767

65535

-32768

32767

65535

long int

21474836
214748364
47
8
Integer types on a 32-bit machine
unsigned long
0
42949672
int
95
Type
Smallest
Largest
value
Value
short int
unsigned short
int
int

unsigned int
C Programming Language - Lecture
2
long int

-32768

32767

65535

214748364
8

21474836
47

42949672
95
9
21474836

Types

The character type in C is an integral type


Character type specifier:
char
signed char
unsigned char

For reasons of efficiency, C compilers are free to treat type char in


either of two ways:
Type char may be a signed integral type equivalent to signed char
Type char may be an unsigned integral type equivalent to unsigned char

Standard C requires that implementations document the range of


their character types in the header file limits.h
EXAMPLES
unsigned char uc
signed char sc =
char c = -1;
int i = uc, j = sc,

= -1;
-1;
k = c;

i must have the value 255


j must have the value 1
it is implementation-defined whether k has the value 255 or - 1
C Programming Language - Lecture
2

10

Types
FIoating-point type specifiers:
float
double
long double (C89)

C does not dictate the sizes to be used for the floatingpoint types or even that they be different
The programmer can assume that the values represent
able in type float are a subset of those in type double,
which in turn are a subset of those in type long double
Standard C requires that the characteristics of the real
floating-point types be documented in the header file
float.h
EXAMPLES
double d;
static double pi;
float coefficients [8] ;
long double epsilon;
C Programming Language - Lecture
2

11

Types
For any type T, a pointer type "pointer to T" may be
formed
Pointer types are referred to as object pointers or
function pointers depending on whether T is an
object type or a function type.
A value of pointer type is the address of an
object or function of type T.
The two most important operators used in conjunction
with pointers are:
the address operator, &, which creates pointer values
indirection operator, *, which dereferences pointers to
access the object pointed to

The size of a pointer is implementation-dependent


and in some cases varies depending on the type of the
object pointed to
C Programming Language - Lecture
2

12

Types
EXAMPLES
int i, j, *ip;
ip = &i;
i = 22;
j = *ip; /* j now has the value 22 */
*ip = 17; /* i now has the value 17 */

Memory
addresses
0x1200

0x1220

ip

0x1240

Variables

C Programming Language - Lecture


2

Memory
locations
0x00
0x00

0x00
0x00

0x00
0x00
13

Types
EXAMPLES
int i, j, *ip;
ip = &i;
i = 22;
j = *ip; /* j now has the value 22 */
*ip = 17; /* i now has the value 17 */

Memory
addresses
0x1200

0x1220

ip

0x1240

Variables

C Programming Language - Lecture


2

Memory
locations
0x00
0x00

0x00
0x00

0x00
0x12
14

Types
EXAMPLES
int i, j, *ip;
ip = &i;
i = 22;
j = *ip; /* j now has the value 22 */
*ip = 17; /* i now has the value 17 */

Memory
addresses
0x1200

0x1220

ip

0x1240

Variables

C Programming Language - Lecture


2

Memory
locations
0x16
0x00

0x00
0x00

0x00
0x12
15

Types
EXAMPLES
int i, j, *ip;
ip = &i;
i = 22;
j = *ip; /* j now has the value 22 */
*ip = 17; /* i now has the value 17 */

Memory
addresses
0x1200

0x1220

ip

0x1240

Variables

C Programming Language - Lecture


2

Memory
locations
0x16
0x00

0x16
0x00

0x00
0x12
16

Types
EXAMPLES
int i, j, *ip;
ip = &i;
i = 22;
j = *ip; /* j now has the value 22 */
*ip = 17; /* i now has the value 17 */

Memory
addresses
0x1200

0x1220

ip

0x1240

Variables

C Programming Language - Lecture


2

Memory
locations
0x11
0x00

0x16
0x00

0x00
0x12
17

Types

Every pointer type in C has a special value called a null pointer, which is
different from every valid pointer of that type
The null pointer constant in C is any integer constant expression with the
value 0
The macro NULL is traditionally defined as the null pointer constant in the
standard header files
It is good programming style to be sure that all pointers have the value
NULL when they are not designating a valid object or function.
Invalid pointers are pointer values that are not NULL but also do not
designate a proper object or function. An invalid pointer is most frequently
created by declaring a pointer variable without initializing it to some valid
pointer or to NULL
Any use of an invalid pointer, including comparing it to NULL, passing it as
an argument to a function, or assigning its value to another pointer, is
undefined in Standard C

EXAMPLES
if (ip != NULL) i = *ip;
Is equivalent to
if (ip) i = *ip;

EXAMPLES
void func( void )
{
int *ip;
if (ip != NULL) /*comparing an invalid poniter*/
}
C Programming Language - Lecture
2

18

Types
The need for a generic data pointer that can be
converted to any object pointer type arises occasionally in
low-level programming.
Standard C introduced the type void* as a "generic pointer
Generic pointers cannot be dereferenced with the * or
subscripting operators, nor can they be operands of addition
or subtraction operators
Type void* is considered to be neither an object pointer nor
a function pointer
EXAMPLES
void *generic_ptr;
int *int_ptr;
char *char_ptr;
generic_ ptr = intytr; /* OK */
int_ptr = generic_ptr; /* OK */
int_ ptr = char_ ptr; /* invalid */
Int_ptr = (int*) char_ptr; /* OK */
void *memcpy(void *s1, const void *s2, size_t n);
C Programming Language - Lecture
2

19

Types
If T is any C type except void, an incomplete type, or a
function type, then the type "array of T" may be declared
The length of the array may be specified by any integer
constant expression
Values of this type are sequences of elements of type T. All
arrays are 0-origin.
These values, known as elements, can be individually selected
by their position within the array
Subscripting or indexing is used to access a particular element
EXAMPLE
int A[3];
A[1] = 100;
A[2] = 200;
A[3] = 300;
is equivalent with
int A[3] = { 0x0064, 0x00C8, 0x012C };

A[0]

Memory
addresses
0x1200

A[1]

0x1202

A[2]

0x1204

Variables

C Programming Language - Lecture


2

Memory
locations
0x64
0x00
0xC8
0x00
0x2C
0x01

20

Types
C doesnt require that subscript bounds to be
checked; if a subscript goes out of range, the
programs behavior is undefined.
An array subscript may be an integer expression
The sizeof operator can determine the size of an
array (in bytes); it returns a value equal with the
product between the length of the array and the
length of one element.
EXAMPLE
int a[10], i;
for ( i = 0; i <= 10 ; i++ )
a[ i ] = 0;

Q: What is wrong with the code above?


Q: What is the value of sizeof operator
applied to array a?
C Programming Language - Lecture
2

21

Types
In C there is a close correspondence between types
"array of T " and "pointer to T":
When an array identifier appears in an expression, the
type of the identifier is converted from "array of T " to
"pointer to T", and the value of the identifier is converted to
a pointer to the first element of the array
The only exceptions to this conversion rule is when the array
identifier is used as an operand of sizeof or address (&)
operators, in which case sizeof returns the size of the entire
array and & returns a pointer to the array (not a pointer to a
pointer to the first element)
Memory
Memory
Variables
addresses
locations
EXAMPLE
A[0]
0x1200
0x00
0x00
int a[10], *ip;
ip = a;

It is exactly as :
ip
0x1214
0x00
0x12
ip = &a[0];
C Programming Language - Lecture
2

22

Types
In C there is a close correspondence between
types "array of T " and "pointer to T":
array subscripting is defined in terms of pointer
arithmetic. That is, the expression a [ i ] is defined
to be the same as * ((a) + (i)), where a is
converted to &a [0]
a[i] is the same as i[a]; so, any pointer may be
subscripted just like an array Memory
Memory
Variables
A[0]

addresses
0x1200

EXAMPLE
int a[10], *ip, i;
ip = a;

ip

0x1214

i = ip[ 1 ]; /* i is equal with a[1] */


i = *(ip+2); /* i is equal with a[2] */

C Programming Language - Lecture


2

locations
0x00
0x00
0x00
0x00
0x12

0x00
0x12

23

Types

Multidimensional arrays are declared as arrays of arrays


The language places no limit on the number of dimensions an array may
have
C stores the arrays in row-major order with row 0 first, then row 1 and so
forth
Memory
Memory
The first dimension of an arrayVariables
may be left empty

a[1][2] is the same as *(*(a+1)+2)


is a pointer to the first 3element subarray
a+1
is a pointer to the second
3-element subarray
*(a+1)
is a pointer to the first
integer in that subarray.
*(a+1) +2
is a pointer to the third
integer in the second 3element subarray.
*(*(a+1) +2) is the third integer in the
second 3-element subarray

row 0

A[0][1]

0x1204

A[0][2]

0x1206

A[1][0]

0x1208

A[1][1]
A[1][2]

row 1

int a[2][3] = { { 1, 2, 3 },
{ 4, 5, 6 } };

addresses
0x1200

A[0][0]

EXAMPLE

0x120A
0x120C

C Programming Language - Lecture


2

locations
0x01
0x00
0x02
0x00
0x03
0x00
0x04
0x00
0x05
0x00
0x06
0x00

24

Types
An enumerated type in C is a set of integer values represented by
identifiers called enumeration constants. The enumeration constants
are specified when the type is defined and have type int
Enumeration tags are in the same overloading class as structure
and union tags, and their scope is the same as that of a variable declared
at the same location in the source program
Identifiers defined as enumeration constants are members of the same
overloading class as variables, functions, and typedef names. Their scope
is the same as that of a variable defined at the same location in the
source program
The first enumeration constant receives the value 0 if no explicit value
is specified
An explicit integer value may be associated with an enumeration constant
Subsequent enumeration constants without explicit associations
receive an integer value one greater than the value associated with the
previous enumeration constant.
EXAMPLE

EXAMPLE

enum sizes { small, medium=10, big, large = 20};

enum state { idle, on, off } state_crt, state_nxt;

Constant name
Small
Medium
Big
Large

enum state state_prev;


state_crt = on;

C Programming Language - Lecture


2

Value
0
10
11
20
25

Types

The structure types in C are collections of named components (also


called members or fields) that can have different types.
Structures are used to store a collection of (logically) related items
The members of a structure are stored in memory in the order they are
declared, with the first component starting at the beginning address of
the structure

EXAMPLE
struct timer {
char en;
char dir;
int val_crt;
int val_up;
int val_dn;
};
struct timer t = { 1,1, 18,2047,0};
Q: What is the value of the sizeof
operator applied to t structure?

Memory layout without


padding
Memory
Memory
Member
addresses
locations
t.en
0x1220
0x01
t.dir
0x1221
0x01
t.val_crt
0x1222
0x12
0x1223
0x00
t.val_up
0x1224
0xFF
0x1225
0x07
t.val_dn
0x1226
0x00
0x1227
0x00
C Programming Language - Lecture
2

26

Types
Holes or padding may appear between any two consecutive
components or after the last component in the layout of a structure if
necessary to allow proper alignment of components in memory
The bit patterns appearing in such holes are unpredictable and may
differ from structure to structure or over time within a single structure

EXAMPLE
struct timer {
char en;
int val_crt;
char dir;
int val_up;
Int val_dn;
};
struct timer t = { 1,18, 1, 2047, 0};
Q: What is the value of the sizeof
operator applied to t structure?

Memory layout with


padding
Memory
Memory
Member
addresses
locations
t.en
0x1220
0x01
0xXX
t.val_crt
0x1222
0x12
0x1223
0x00
t.dir
0x1221
0x01
0xXX
t.val_up
0x1224
0xFF
0x1225
0x07
t.val_dn
0x1226
0x00
0x1227
0x00
C Programming Language - Lecture
2

27

Types
C allows the programmer to pack integer components into

spaces smaller than the compiler would ordinarily allow. These


integer components are called bit fields
A bit field of n bits can represent unsigned integers in the range 0
through 2n-1 and signed integers in the range -2 n-1 through 2n-1-1
The precise manner in which components (and especially bit
fields) are packed into a structure is implementation-dependent
The use of bit fields is therefore likely to be nonportable.
EXAMPLE
struct {
unsigned Offset : 16;
unsigned Page : 8;
unsigned Segment : 6;
unsigned UNUSED : 1;
unsigned Supervisor : 1;
} virtual address;

Byte
11
6

Byte
8

Page

Segment

Byte

C Programming Language - Lecture


2

Byte
16
Offset
28

Types

Compilers are free to impose constraints on the


maximum size of a bit field and specify certain addressing
boundaries that bit fields cannot cross
These alignment restrictions are usually related to the
natural word size of the target computer
When a field is too long for the computer, the compiler
will issue an appropriate error message
When a field would cross a word boundary, it may be
moved to the next word
An unnamed bit field may also be included in a structure to
provide padding between adjacent components
Unnamed bit fields cannot be referenced, and their
contents at run time are not predictable
Specifying a length of 0 for an unnamed bit field has a
special meaning: no more bit fields should be packed into
the area in which the previous bit field
C Programming Language - Lecture
2

29

Types
EXAMPLE
struct S {
unsigned a : 4;
unsigned : 2;
unsigned b : 6;
};

Byte
4
2

Byte
6

EXAMPLE
struct S {
unsigned a : 4;
unsigned : 0;
unsigned b : 6;
};

Byte
4
a

Byte
12

Byte
6

Byte
10

C Programming Language - Lecture


2

30

Types

A union consists of one or more members, possible of different types


The compiler allocates only enough space for the largest of the
members, which overlay each other within this space
Assigning a new value to one member alters of the others members as well
Each component of a union type is allocated storage starting at the
beginning of the union
A union can contain only one of its component values at a time
EXAMPLE
union U {
int i;
char c;
long l;
};

Byte

Byte

Byte

Byte

i
c
l

C Programming Language - Lecture


2

31

Types

The type "function returning T


" is a function type, where T may
be any type except "array of ...
" or "function returning ....
Functions may not return arrays
or other functions, although they
can return pointers to arrays and
functions
Functions may be introduced in
only two ways:
A function definition can
create a function, define its
parameters and return value,
and supply the body of the
function
A function declaration can
introduce a reference to a
function object defined elsewhere

EXAMPLE
extern int f(), (*fp) (), (*apf [ ] ) (double);
int i, j, k;
i = f(14);
i = (*fp) (j, k);
i = (*apf [ j ])(k);
extern int f () ;
int (*fpl) (), (*fp2) ();
fpl = f; /* implicit conversion to pointer */
fp2 = &f; /* explicit manufacture of a pointer */

The only operations on an


expression of function type are
converting it to a function
pointer and calling it
C Programming Language - Lecture
2

32

Types

Type definitions are


an important tool for
writing portable
programs
Type definitions can
make a program more
understandable
Type definitions can
make a program
easier to modify
Declarations with the
typedef do not
introduce new types:
the names are
considered to be
synonyms for types
that could be
specified in other
ways (create
compatible types)

EXAMPLE
typedef type new_type_name;
typedef
typedef
typedef
typedef
typedef
typedef
typedef

int uint16_t;
int *IP;
int (*FP) ();
int F(int);

/* pointer to int * /
/* pointer to function returning int */
/* function with one int
parameter, returning int */
double A5[5];
/* 5-element array of
double" */
int A[ ];
/ * array of int * /
struct S { int a; int b; } stype; /* structure type */

IP ip;
IP tip () ;
FP fp;
F *fp2 ;
A5 a5;
A5 a25 [2] ;
A a;
A *ap3 [3] ;

/* pointer to an int */
/* function returning a pointer to
int */
/* pointer to a function returning int */
/* pointer to a function taking an
int parameter and returning an int */
/* 5-element double array */
/* a 2-element array
of 5-element arrays of double */
/* array of int (with unspecified bounds) */
/* 3-element array of pointers to
arrays of int (with unspecified bounds) */

C Programming Language - Lecture


2

33

Types
The type void has no values and no operations
Type void is used:
as the return type of a function, signifying that the
function returns no value
in a cast expression when it is desired to explicitly
discard a value
to form the type void *, a "universal" data pointer
in place of the parameter list in a function declarator
to indicate that the function takes no arguments
EXAMPLE
void main( void )
void func( int i )
int func( void )
(void)(x++ || y--);
void *memcpy(void *s1, const void *s2, size_t n);
C Programming Language - Lecture
2

34

Conversions
The C language provides for values of one type to
be converted to values of other types under
several circumstances:
A cast expression may be used to explicitly convert a
value to another type
An operand may be implicitly converted to another
type in preparation for performing some arithmetic or
logical operation
An object of one type may be assigned to a location
(lvalue) of another type, causing an implicit type
conversion
An actual argument to a function may be implicitly
converted to another type prior to the function call
A return value from a function may be implicitly
converted to another type prior to the function return
C Programming Language - Lecture
2

35

Conversions
The casting conversions allows an
object to be explicitly converted to
another type
Permitted casting conversions
Destination (cast) type

Permitted source types

any arithmetic type

any arithmetic type

any integer type

any pointer type

pointer to (object) T
(void *)

any integer type


(void *)
pointer to (object) Q, for any Q

pointer to function

any integer type


pointer to (function) Q, for any Q

structure or union

none; not a permitted cast

array of T or function returning T

none; not a permitted cast

void

any type

C Programming Language - Lecture


2

36

Conversions
In a simple assignment expression, the types of the
expressions on the left and right sides of the
assignment operator should be the same
If they are not, an attempt will be made to convert
the value on the right side of the assignment to the
type on the left side
Permitted assignment conversions
Left side type

Permitted right side types

any arithmetic type

any arithmetic type

a structure or union type

a compatible structure or union type

(void*)

the constant 0
pointer to object T
(void *)

Pointer to (object) T

the constant 0
pointer to Q, where T an Q are compatible
(void *)

pointer to (function) T

the constant 0
Pointer to F, where T and F are compatible
C Programming Language - Lecture
2

37

Conversions
The usual unary
conversions determine
whether and how a single
operand is converted before
an operation is performed

Conversion rank
Ran
k

Types of the rank

60

long long int, unsigned long


long int

50

long int, unsigned long int

40

int, unsigned int

30

short, unsigned short

If the operand has type

char, unsigned char, signed


char
Standard C coverts it to

float

(no conversion)

array of T

pointer to T

function returning T

pointer to function returning T

an integer type of rank greater or equal to int

(no conversion)

an unsigned type of rank less than int, all of whose


values can be represented in type int

int

an unsigned type of rank less than int, all of whose


values cannot be represented in type int

unsigned int

Usual unary conversions (choose first that applies)

20

C Programming Language - Lecture


2

38

Conversions
When two values must be operated on in
combination, they are first converted
according to the usual binary conversions to
a single common type, which is also
typically the type of the result
Usual binary conversions (choose first that applies)
If either operand has type

And the other operand has


type

Standard C converts both to

long double

any real type

long double

double

any real type

double

float

any real type

float

any unsigned type

any unsigned type

the unsigned type with the


greater rank

any signed type

any signed type

the signed type with the greater


rank

any unsigned type

any signed type of less or equal


rank

the unsigned type

any unsigned type

a signed type of greater rank


the signed type
that can represent all values of
the
unsigned type
C Programming
Language - Lecture
2
a signed type of greater
rank
the unsigned version of the

any unsigned type

39

Q&A
1.
2.

Can there be padding at the beginning of a structure?


What type would you choose to represent:
1.
2.
3.

3.

Which conversions are allowable in Standard C?


1.
2.
3.
4.

4.

char int
char* int *
double* int
int * t (where: typedef int t;)

Which of the following types are not legal in C?


1.
2.
3.
4.
5.

5.

A six digit postal code


The values 0 and 1
A phone number with a two digit area code and 6 digit local number

short unsigned int


short float
long double
unsigned long
unsigned double

Which is the value and type of the following expressions?


char c = \1; short s = 2; int i = -3; long m = 5; float f = 6.5f; double d = 7.5;
1.
c*i
2.
s+m
3.
f/c
4.
d/s
5.
f-d
6.
(int)f

C Programming Language - Lecture


2

40

S-ar putea să vă placă și