Tower of Hanoi

Download Report

Transcript Tower of Hanoi

C What you Know*
• Objective: To introduce some of the features of C.
This assumes that you are familiar with C++ or
java and concentrates on the features that are not
used in C++.
• C does not have the OOP features of C++, nor
does it have as rich a library
– no classes
– I/O, string operations, and dynamic memory
management done through library calls
– Not much support for higher level data structures (e.g.
STL)
– Commonly lots of pointer manipulation
Topics
•
•
•
•
•
•
Getting Started
pointers
character arrays and string functions
structs
I/O
dynamic memory (malloc and free)
Hello, World!
#include <stdio.h>
int main()
{
printf(“Hello World\n”);
return 0;
}
$ gcc -o hello hello.c
$ ./hello
Hello
Pointers
• To declare a pointer put * in front of the variable
name.
– int i;
/* declare an int */
– int *ip;
/* declare a pointer to an int */
– char *name; /* declare a pointer to */
/*
a character */
• Use & to get the address of a variable and * to
dereference a pointer
– ip = &i;
– i = *ip;
/* assign the pointer variable */
/* ip the address of i */
/* assign i the value of what */
/*
ip points to. */
Pointers and Arrays
• Arrays are related to pointers. An array variable is
a pointer to the first location in the array.
– declare static character array of size 10
• char name[10];
– can initialize character arrays
• char name[10] = “Fred”;
– char *anotherName;
– anotherName = Name;
• You can use pointer arithmetic to access array
elements
– access 4th element of name
• name[4];
• *(name + 4);
character arrays (strings)
• In C, there is no built-in support for strings.
Instead strings are represented as null-terminated
character arrays.
F
name
• char name[7];
• name = “Fred”
/* compiler adds ‘\0’ */
• name[0] = ‘F’; name[1] = ‘r’;
• name[2] = ‘e’; name[3] = ‘d’;
• name[4] = ‘\0’
r
e
d
\0
Library Support for Strings
• #include <string.h>
• strlen( const char *s );
– returns length of s (not including \0)
• int strcmp( const char *s1,
const char *s2 );
– return 0 if s1 == s2, <0 if s1 < s2, >0 if s1 > s2
• strcat( char *dest, const char *src );
– appends src to the end of dest
– char D[20]; D[0] = ‘\0’;
– strcat(D,”Jeremy”); strcat(D,” “); strcat(D,”Johnson”);
• strncat( char *dest,
const char *src, int n )
– appends upto n characters of src to the end of dest
Library Support for Strings
• char* strcpy( char *dest,
const char *src );
– copy the string pointed to by src (including ‘\0’) to a
character array pointed to by dest.
– dest must already point to a character array with
sufficient space to hold src.
– no error checking for insufficient space
• char* strncpy( char *dest,
const char *src, int n );
– copy at most n characters from the string pointed to by
src to a character array pointed to by dest.
– This should be used to prevent overflow errors.
structs
• A struct is used to group various data fields in a
single type (classes without methods)
• typedef can be used to give a name to a particular
struct declaration.
• Use “.” operator to access different fields.
typedef struct Employee Employee;
struct Employee {
char
*name;
double wage;
int
id;
}
Employee worker;
worker.name = “Fred”;
worker.id = 1;
worker.wage = 15.25;
Arrays of Arrays
• char *names[8];
• names[0] = “start”;
names
s
t
a
r
t
\0
m
i
d
d
l
e
e
n
d
\0
…
…
\0
I/O
<stdio.h>
• #include
• stdin, stdout, stderr
– standard input, standard output, and standard error file
streams
• character I/O
– int getchar()
• read a single character from stdin – if none available return
EOF (end-of-file)
• getchar() is a macro that uses getc
– int getc( FILE *FP )
• read a single character from the file or stream identified by FP
– int putchar( char c )
• write the character c to stdout – if successful return the the
character c otherwise EOF.
– int putc( char c, FILE *FP )
• write the character c to the file or stream identified by FP
mycat.c
$ gcc mycat.c -o mycat
$ ./mycat < mycat.c
/* read character stream from stdin, copy to stdout */
#include <stdio.h>
int main()
{
int c;
while ( (c = getchar()) != EOF )
putchar( (char)c );
return 0;
}
Formatted Output
• printf prints a variable number of arguments using a specified
format which is represented by a string
– int printf( const char *FORMAT
[, ARG, ...]);
– FORMAT is a string of characters (including special characters such
as ‘\n’ for newline, and conversion formats for different types
(with optional width and precision information).
– man 3 printf
# for more info
– %d int
– %c character
– %s string
– %f, %e, %g floating point number
– %4.2f (4 indicates width, 2 precision, i.e. xx.xx)
– %x hexadecimal int
– %o octal int
Example
#include <stdio.h>
int main()
{
typedef struct Employee Employee;
struct Employee {
char
*name;
double wage;
int
id;
};
Employee worker;
worker.name = "Fred";
worker.id = 1;
worker.wage = 15.25;
printf( "%s earns $%4.2f per hour\n",
worker.name, worker.wage );
return 0;
}
Example
/* a program illustrating character arrays and pointer
arithmetic */
#include <stdio.h>
#include <string.h>
int main() {
char name[20] = "Fred";
char *anothername;
anothername = name;
printf( "name = %s\n",name );
printf( "Another name for %s is %s\n“,
name, anothername );
printf( "The %d-th letter of %s = %c\n",
strlen(name), name, name[3] );
printf( "The %d-th letter of %s = %c\n",
strlen(name), name, *(name+3) );
return 0;
}
Formatted Input
• scanf is used to read a variable number of
arguments with input format specified by a fomat
string similar to printf.
– int scanf(const char *FORMAT
[, ARG, ...]);
– The arguments to scanf are the addresses to the
variables passed – this is required since the input
variables will be modified
– There must be sufficient arguments for the number of
specified conversion types or unpredictable behavior
may result
– There must be sufficient space in the arguments (e.g.
character arrays) to hold the input or unpredictable
behavior may result
Example
int main()
{
char name[MAXNAMELEN];
/* fixed size array */
/* prompt the user to enter their name and
read the string.
*/
/* "%s" tells scanf to read a string,
which it stores in the array name.
*/
/* A string is read until whitespace is
encountered.
*/
/* The address of the name must be
passed to scanf.
*/
printf("Enter first name\n");
scanf("%s",name);
printf("Hello %s\n",name);
return 0;
}
Dynamic Memory Allocation
• In C, dynamic memory is allocated through the
use of a library routine called malloc.
• malloc inputs the desired amount of memory in
bytes (use the sizeof macro to help determine
the number of bytes needed) and returns a pointer
(if successful) to the newly allocated memory. If
unsuccessful, malloc returns NULL.
• The return type is void*, which is a generic
pointer, since what the memory will be used for
varies. A typecast should be used after calling
malloc.
free and realloc
• When the memory allocated by malloc is no
longer in use, it should be freed using free.
– Not doing this causes a memory leak, which can cause
problems when lots of memory is required.
– freeing memory when it is still being used is a common
bug; one that may be difficult to find.
• realloc can be used to obtain additional
memory when the amount requested is insufficient
(see grow from the text)
– void *realloc( void *APTR, size_t NBYTES );
– void free( void *APTR );
Example (1/2)
#include <stdlib.h>
int main()
{
typedef struct Employee Employee;
struct Employee {
char
*name;
double
wage;
int
id;
};
Employee *worker;
/* allocate space for an Employee */
worker = (Employee *) malloc( sizeof( Employee ));
/* check for NULL - see emalloc in the text. */
if (worker == NULL) {
printf("malloc failed\n");
exit(1);
}
Example (2/2)
/* -> operator: dereference fields of a struct given a
ptr to the struct */
worker->name =
malloc( (strlen("Fred")+1) * sizeof(char) );
/* same as (*worker).name */
strcpy( worker->name, "Fred" );
worker->id = 1;
worker->wage = 15.25;
printf( "%s earns $%4.2f per hour\n",
worker->name, worker->wage);
/* free space allocated for worker */
free( worker->name );
free( worker );
return 0;
} /* main */
Lists in C
typedef struct Nameval Nameval;
struct Nameval {
char
*name;
int
value;
Nameval
*next; /* in list */
};
/* newitem: create new item from name and value */
Nameval* newitem( char *name, int value )
{
Nameval *newp;
newp = (Nameval*) emalloc( sizeof( Nameval ));
newp->name = name;
newp->value = value;
newp->next = NULL;
return newp;
}
Lists in C
/* addfront: add newp to front of listp */
Nameval* addfront( Nameval *listp, Nameval *newp
)
{
newp->next=listp;
return newp;
}
nvlist = addfront( nvlist, newitem( “smiley”,
0x263A ));
char** Again
• One must be careful when using multiple
pointers to the same memory.
– char name[10] = “Fred”;
– char *anothername;
– anothername = name;
• If name changes so does anothername.
• If you want a copy, allocate additional
memory and copy (strdup does this).
Example
#include <stdio.h>
#include <string.h>
int main() {
char name[20] = "Fred";
char *anothername;
anothername = name;
printf( "name = %s\n", name );
printf( "Another name for %s is %s\n",
name, anothername );
name[3] = 'e';
printf( "name = %s\n", name);
printf( "anothername has also changed to %s\n",
anothername);
/* the following causes problems since name and
anothername point to the same space. */
free( anothername );
printf( "name = %s\n", name ); /* Bad! */
return 0;
}
Command Line Arguments
• The main function can take optional arguments to
provide access to the command line arguments
when it is executed in a Unix environment.
– int argc /* number of command line
args*/
– char **args; /* an array of strings
(character arrays) containing the
name of the arguments. The 0th
element in args is the command – name
of the executable file that contains
the program. */
Example (1/2)
/* generate a sequence of n random numbers in
the range 1..u */
#include <stdlib.h>
#include <stdio.h>
#define DEFLENGTH 10
#define DEFRANGE 1000
int main( int argc, char **argv )
{
int n, u, i;
n = DEFLENGTH;
u = DEFRANGE;
Example (2/2)
if (argc != 3)
{
printf( "usage: %s n u\n", argv[0] );
exit( 1 );
}
n = atoi( argv[1] );
u = atoi( argv[2] );
for( i=0; i<n; i++ )
{
printf( "NR == %d\n", (rand() % u) + 1 );
}
return 0;
} /* main */