c what you know* objective: to introduce some of the features of c. this assumes that you are...
TRANSCRIPT
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$ ./helloHello
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 */– i = *ip; /* 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.
• char name[7];• name = “Fred”
/* compiler adds ‘\0’ */• name[0] = ‘F’; name[1] = ‘r’; • name[2] = ‘e’; name[3] = ‘d’;• name[4] = ‘\0’
F
r
e
d
\0
name
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”;
s t a r t \0
e n d \0
m i d d l \0e
…
…
names
I/O• #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– 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
Exampleint 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 Ctypedef 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 */