Vous êtes sur la page 1sur 28

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; /* assign the pointer variable */ /* ip the address of i */ /* assign i the value of what */ /* ip points to. */

i = *ip;

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 m e n d \0 i d d l e \0 s t a r t \0

#include <stdio.h> 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

I/O

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).

#include <stdio.h> #include <string.h> int main() { char name[20] = "Fred"; char *anothername;

Example

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 */

Vous aimerez peut-être aussi