I'm no expert at C (hence I wrote this guide for my own education) so please take every care when reading it. I've checked most of it, but please refer to a formal C reference before assuming it is correct. And feel free to point out any errors, no matter how trivial. I also welcome suggestions for additional material; there's a mailto at the bottom of this page. My thanks to the anonymous person from Bell Canada for many helpful observations.
C is case-sensitive. That is, the identifier myVar
is different to myvar
, whereas in Pascal they would be
the same.
{ ... }
and
(* ... *)
are replaced by
/* ... */
Use
// ...
for a single-line comment, which is not available in Pascal.
Pascal's type
has no equivalent in C.
type myType = integer;
becomes
typedef myType int;
For Pascal record
s (C struct
s), it is a little more complicated:
date_t = record
date : integer;
month : integer;
year : integer;
end;
becomes
struct date_tag {
int date;
int month;
int year;
};
but it doesn't end there since the date_rec_tag
is
not actually a type in C. There is another step required to create a
type for a structure in C.
In Pascal, the identifier associated with a record definition becomes a stand-alone type. However, in C, the identifier is only a subsititute for the structure—it does not actually become a type. It is actually known as a structure tag. To define a type for a structure, add the following:
typedef struct date_tag date_t
const x = 10;
is replaced by
#define x 10
(note there is no terminating semi-colon). Also, ANSI C allows the following constant declaration:
const int x = 10;
var
has no equivalent in C. Variables can be declared anywhere.
The format for a var declaration is simpler in C:
var x : integer;
becomes
int x;
Pascal's
Inc(x);
routine is replaced with
x++;
where X is incremented after other operations, a behaviour known as post-increment, the pre-increment behaviour is invoked by:
++x;
You can also use the following syntax:
x += 1;
C does not handle expressions like float = (integer / integer) very well, in that it forces the type of the result to the type that best handles the result. For instance, from the code:
int intX;
int intY;
float fltZ;
fltZ = intX / intY;
The order is char, int, long, float, double. The compiler uses the earliest in the order that still handles the result. To obtain a floating-point result, use typecasting, thus:
fltZ = (float)intX / (float)intY;
Pascal's case
statement is somewhat different
in C. The following:
case key of
27: writeln( 'Escape key pressed' );
13: writeln( 'Tab key pressed' );
else
writeln( 'Unrecognised key pressed' );
end;
becomes
switch (key) {
case 27:
printf( "Escape key pressed\n" );
break;
case '9':
printf( "Tab key pressed\n" );
break;
default;
printf( "Unrecognised key pressed\n" );
}
Note that you have to use the break
statement
to end execution for a particular case; if you don't use it, the following
case
(s) will also be executed until either a
break
statement or the closing brace is
encountered.
if x = 1 then y = 3;
becomes
if (x == 1) y = 3;
in C. Note that brackets are required around the condition, and
note also the difference between the assignment =
and
equality ==
operators.
WARNING: Pascal's assignment (‘becomes’) operator
:=
is a single equals sign in C: =
. The equality
operator is a single equals sign for Pascal and a double equals sign in C
==
. This is a cause of a common bug—it is very easy to
accidentally write something like this:
if (x = 1) doSomething();
The problem with this statement is that it will always be true,
since the single equals is an assignment operator, and the
asiignment operator always returns a result of ‘true’,
hence the doSomething()
function would always be called.
Pascal's logical operators are different thus:
or
becomes
||
whilst
and
becomes
&&
The inequality test (not equal to) in Pascal is
<>
but in C, it is
!=
Pascal's
repeat ... until <condition>;
is replaced by
do { ... } while (<condition>);
Pascal's
while, begin ... end
TODO
Because C's implementation of the for
statement
allows the programmer to specify the operation and tests that is
performed at each loop, and the variables in these operations need
not have any relation to each other, it is very flexible and can be
used in many situations. In contrast, Pascal's for
loop
only considers the value of the given index variable for the start
and end conditions, and only increments the same variable.
for x = 1 to 100
begin
end;
becomes
for (x = 1; x <= 100; x++ )
{
}
The first statement sets the starting value of the loop variable, whilst the second statement is not a terminating condition, but a continuation condition. Finally, the last statement is performed with each iteration of the loop; in this case, we merely increment the loop variable by one, but we could put anything in there.
In C, all subroutines are functions, which can return values. To emulate
Pascal's procedure
(i.e. a subroutine that does not return a
value), just ignore the return value. Thus,
procedure myProcedure( myInt : integer );
becomes
void myProcedure( int myInt )
The initial void
is the return type for the function; in this
case, no value is returned hence void
. Note that the C does not
terminate the function name header with a semicolon.
If a C function does not take any input parameters, the parameter list
should be declared void
, for instance:
void myProcedure( void )
The begin end
pair that contain the code for a
routine are replaced with the curly brackets for C. Also, variables
that are local to the routine should be declared within the curly
braces, unlike Pascal, where the vars appear before the begin
end
pair. Thus:
procedure myProcedure();
var
myInt : integer;
begin
...
end;
becomes
void myProcedure(void)
{
int myInt;
...
}
Execution of a C function (that doesn't return a value) is ended with:
return;
There can be more than one return
statement in a routine, but
the last statement is usually a return
. The return
is optional if the function doesn't return a value.
The return value of a Pascal function is specified by assigning the value to the function's name within the function itself. However, in C, the value is returned with the return statement thus:
function myFunction() : integer;
var
myInt : integer;
begin
...
myFunction = myInt;
end;
becomes
int myFunction( void )
{
int myInt;
return myInt;
}
Parameter passing frequently uses pointers; pointers in C are (in my
opinion) very confusing, so see the page on
pointers and dynamic memory for more confusion
information ;-).
To pass by value:
procedure myProcedure( myVar : integer );
becomes
void myProcedure( int myVar )
This enables the function to change the value of myVar
(the formal parameter) within the function
without changing the value of the corresponding (actual) parameter in the
caller. To refer to the address of myVar
in the
function, use the &
operator. For example:
void myProcedure( int myVar )
{
printf( "myVar's value = %d\n", myVar );
printf( "myVar's memory address = %x\n", &myVar );
}
If, in contrast, the function must change the value of a parameter as stored by its caller, the formal parameter (i.e. the variable identifier in the function header) must be prefixed with the * operator, so that it is passed by reference, thus:
void myProcedure( int *myVar )
{
printf( "myVar's value = %d\n", *myVar );
printf( "myVar's memory address = %x\n", myVar );
}
Note that the references to the variable inside the function have to be changed; when the input parameter is passed by reference (i.e. an address), its value is obtained by prefixing its identifier with an asterisk, whilst its address is obtained directly (without any prefix).
Essentially, to make a C parameter a Pascal var
parameter,
turn it into a pointer by prepending an asterisk. Within the function, refer
to the value also by prepending an asterisk.
In the caller, the function call must use the address of the variable.
void myCaller( void )
{
int myInt;
myInt = 99;
printf( "myInt before = %d\n", myInt );
myProcedure( myInt* );
printf( "myInt after = %d\n", myInt );
}
Home | About Me | Copyright © Neil Carter |
Content last updated: 2012-07-12