31
15-213 C Primer Session – 1/25/01 Outline • Hello World • Command Line Arguments • Bit-wise Operators • Dynamic Memory / Pointers • Function Parameters • Structures

15-213 C Primer Session – 1/25/01

  • Upload
    nasnan

  • View
    38

  • Download
    0

Embed Size (px)

DESCRIPTION

15-213 C Primer Session – 1/25/01. Outline Hello World Command Line Arguments Bit-wise Operators Dynamic Memory / Pointers Function Parameters Structures. 1. Hello World. #include int main( int argc, char *argv[]) { printf(“Hello World\n”); return 0; }. - PowerPoint PPT Presentation

Citation preview

Page 1: 15-213 C Primer Session – 1/25/01

15-213 C Primer Session – 1/25/01

Outline• Hello World• Command Line Arguments• Bit-wise Operators• Dynamic Memory / Pointers• Function Parameters• Structures

Page 2: 15-213 C Primer Session – 1/25/01

1. Hello World

#include <stdio.h>

int main(int argc, char *argv[]){ printf(“Hello World\n”); return 0;}

Page 3: 15-213 C Primer Session – 1/25/01

Hello World (Ver. 2)

#include <stdio.h>

#define MYSTRING “Hello World\n”

int main(int argc, char *argv[]){ printf(MYSTRING); return 0;}

Page 4: 15-213 C Primer Session – 1/25/01

Hello World (Ver. 3)

#include <stdio.h>

#ifdef HELLO#define MYSTRING “Hello World\n”#else#define MYSTRING “Goodbye World\n”#endif

int main(int argc, char *argv[]){ printf(MYSTRING); return 0;}

Page 5: 15-213 C Primer Session – 1/25/01

2. Command Line Arguments

• ls –l *.txt– How does a program obtain the ‘-l’

and ‘*.txt’?– Use the argc and argv parameters to

main()• argc – Number of arguments (including

program name)• argv – Array of strings of all arguments

(including program name)

Page 6: 15-213 C Primer Session – 1/25/01

#include <stdio.h>

main(int argc, char *argv[]){ int j, sum; char *pchar;

printf ("Program called : %s\n", *argv ); /* print 0th arg, program called */

if ( argc < 4 ) printf ( "Not enough arguments\n" ); /* see if enough args to perform op */ else { pchar = *(argv + 1); /* get pointer to 1st arg */ if ( *pchar == '+' ) /* if +, continue */

{ sum = 0; printf ( "Numbers : " ); for ( j = 2; j < argc; j++ ) { sum += atoi ( *(argv + j) ); /* each arg -> int, add to sum */ printf ( "%s ", *(argv + j) ); /* print argument */ } printf ( "\nSum : %i\n", sum ); /* print sum */}

elseprintf ( "Unsupported\n" ); /* operation unsupported */

}}

Page 7: 15-213 C Primer Session – 1/25/01

3. Bit-wise OperatorsExample Problems

/* * bitNor - ~(x|y) using only ~ and & * Example: bitNor(0x6, 0x5) = 0xFFFFFFF8 * Legal ops: ~ & * Max ops: 8 * Rating: 1 */int bitNor(int x, int y) {

}

return (~x & ~y);

Page 8: 15-213 C Primer Session – 1/25/01

/* * logicalShift - shift x to the right by n, * using a logical shift * Can assume that 1 <= n <= 31 * Examples: logicalShift(0x87654321,4) = 0x08765432 * Legal ops: ~ & ^ | + << >> * Max ops: 16 * Rating: 3 */int logicalShift(int x, int n) {

}

/* Shift normally, using XOR to clear any bits * on the left of the result that should always * be 0 instead of the sign */

return (x >> n) ^ (((x & (1 << 31)) >> n) << 1);

Page 9: 15-213 C Primer Session – 1/25/01

/* * bang - Compute !x without using ! * Examples: bang(3) = 0, bang(0) = 1 * Legal ops: ~ & ^ | + << >> * Max ops: 12 * Rating: 4 */int bang(int x) {

}

int minus_x = ~x+1;

/* Cute trick: 0 is the only value of x * for which neither x nor -x are negative */

int bits = (minus_x | x) >> 31; /* -1 or 0 */return bits + 1;

Page 10: 15-213 C Primer Session – 1/25/01

4. Dynamic Memory & Pointers

• Java manages memory for you, C does not– C requires the programmer to allocate and

unallocate memory• For instance, int x tells C to allocate 4 bytes for

an integer

– Unknown amounts of memory can be allocated dynamically during run-time with malloc() and unallocated using free()

Page 11: 15-213 C Primer Session – 1/25/01

Code!#include <stdio.h> #include <string.h>

#define HELLO_MIXED "Hello world!"#define HELLO_CAPS "HELLO WORLD!"

int main (int argc, char *argv){ char *original_string; char *copied_string; int index;

/* Allocate space for the string. * Strings are terminated with a NULL. * Don't forget to include space for this terminator. */ original_string = (char *) malloc (strlen (HELLO_MIXED) + 1); if (!original_string) { printf ("malloc() has failed\n"); exit (-1); }

Page 12: 15-213 C Primer Session – 1/25/01

/* Initialize the string */strncpy (original_string, HELLO_MIXED, strlen (HELLO_MIXED));

/* 1st attempt to copy the string */copied_string = original_string;

/* It looks like it worked */printf ("Original String: %s\nCopied String: %s\n\n", original_string, copied_string);

/* Now, let's change the original string to be all uppercase */strncpy (original_string, HELLO_CAPS, strlen (HELLO_CAPS));

/* Let's take a look at those two strings again */printf ("Original String: %s\nCopied String: %s\n", original_string, copied_string);

/* What happened? We copied the address, not the content. * We made an alias */printf ("Original String address: 0x%p\nCopied String Address: 0x%p\n\n", original_string, copied_string);

Page 13: 15-213 C Primer Session – 1/25/01

/* To fix this, we could allocate space * for a new string using malloc() * and then use strncpy() to copy the contents, as before. But, we * can actually do this in one step with strdup() */copied_string = strdup(original_string);

/* Now, let's test things again */

/* They look the same, but are they actually different? */printf ("Original String: %s\nCopied String: %s\n\n", original_string, copied_string);

/* Let's see */strncpy (original_string, HELLO_MIXED, strlen (HELLO_CAPS));

/* Perfect. This time it works */printf ("Original String: %s\nCopied String: %s\n", original_string, copied_string);printf ("Original String address: 0x%p\nCopied String Address: 0x%p\n\n", original_string, copied_string);

Page 14: 15-213 C Primer Session – 1/25/01

/* Strings are actually arrays of characters. We can access the * characters, including the NULL, one at a time by using their * address. Notice the use of the * operator to dereference a * character pointer. Also notice that the pointer moves by * one byte each time -- what one would expect from "++". */

/* Notice strlen() + 1. strlen() doesn't count the NULL, * but we want to see it */for (index=0; index < (strlen (original_string) + 1); index++){ printf ("0x%p: %c (%d)\n", original_string + index, *(original_string + index), (int)*(original_string + index));}printf ("\n");

Page 15: 15-213 C Primer Session – 1/25/01

/* We can also use a shortcut notation: original_string[index]. * The preprocessor will convert this to *(original_string + index) * for us */

for (index=0; index < (strlen (original_string) + 1); index++){ printf ("0x%p: %c (%d)\n", original_string + index, original_string[index], (int)original_string[index]);}

/* Lastly, let's give back the space that we allocated * I like to set the pointers to NULL to indicate that * they are not allocated. */free (original_string);original_string = NULL;

free (copied_string);copied_string = NULL;

return 0;}

Page 16: 15-213 C Primer Session – 1/25/01

Integer Arrays#include <stdio.h>

#define ARRAY_COUNT 5

int main (int argc, char *argv){ int *int_array; int index;

/* Allocate space for the ints * Only strings are null terminated -- int arrays are not. * * Here, the use of sizeof() is critical * -- ints are more than 1 byte */ int_array = (int *) malloc (ARRAY_COUNT * sizeof(int)); if (!int_array) { printf ("malloc() has failed\n"); exit (-1); }

Page 17: 15-213 C Primer Session – 1/25/01

/* Initialize the array */for (index=0; index < ARRAY_COUNT; index++){ *(int_array + index) = index;}

/* Make sure it worked * Notice the use of the & operator. This returns the address of * an object in memory. */for (index=0; index < ARRAY_COUNT; index++){ printf ("int_array[%d]=%d at address 0x%p (decimal %d)\n", index, int_array[index], &(int_array[index]), &(int_array[index]));}printf ("\n");

Page 18: 15-213 C Primer Session – 1/25/01

/* But wait! Why did that work? We only added one, * and integers are larger than one byte. * * The joys of "Pointer Arithmetic". When adding or * incrementing pointers, C automatically adds or * increments multiples of the size of the data type. * * Take a second look at the output of the loop and the * addresses. * * Now, take a look at the size of int printed below */printf ("sizeof(int) = %d bytes", sizeof(int));printf ("\n");

/* Clean-up */free (int_array);int_array = NULL;

return 1;}

Page 19: 15-213 C Primer Session – 1/25/01

5. Function Parameters

• Function arguments are passed “by value”.

• What is “pass by value”?– The called function is given a copy of the

arguments.

• What does this imply?– The called function can’t alter a variable in

the caller function, but its private copy.

Page 20: 15-213 C Primer Session – 1/25/01

Example 1

Example 1:

void swap_1(int a, int b){

int temp;

temp = a;a = b;b = temp;

}

Q: Let x=3, y=4,

after swap_1(x,y);

x =? y=?

A1: x=4; y=3;

A2: x=3; y=4;

Page 21: 15-213 C Primer Session – 1/25/01

Example 2: swap_2

Example 2:

void swap_2(int *a, int *b){

int temp;

temp = *a;*a = *b;*b = temp;

}

Q: Let x=3, y=4, after

swap_2(&x,&y); x =? y=?

A1: x=3; y=4;

A2: x=4; y=3;

Page 22: 15-213 C Primer Session – 1/25/01

Example 3: scanf

Example 3:

#include <stdio.h>

int main(){

int x;scanf(“%d\n”, &x);printf(“%d\n”, x);

}

Q: Why using pointers in scanf?

A: We need to assign the value to x.

Page 23: 15-213 C Primer Session – 1/25/01

Using Libraries

• What are libraries?• Using libraries

• Finding library functions> man printf

#include <stdio.h>...printf(“Hello, world!\n”);...

Page 24: 15-213 C Primer Session – 1/25/01

I/O operations

• Header: stdio.h• Functions:

void printf(char * format, ...);int scanf(char * format, ...);...

Page 25: 15-213 C Primer Session – 1/25/01

String operations

• Header: string.h• Functions:

int strlen(char * str);int strcmp(char * str1, char * str2);char * strcpy(char * dest, char * orig);char * strchr(char * str, char ch);...

Page 26: 15-213 C Primer Session – 1/25/01

6. Structures

• Structures enables a programmer to group together related data– Sort of like a class, but structures only

encapsulate data

Page 27: 15-213 C Primer Session – 1/25/01

More Code!#include <stdio.h>#include <string.h>#include <malloc.h>

#define MAX_STRING 20#define MAX_STUDENTS 6

/* A C struct is a data type that groups of objects of * possibly different types into a single object. */struct student { char first[MAX_STRING]; char last[MAX_STRING]; char id[MAX_STRING]; int age;}; int main(int argc, char **argv){ int n, index;

Page 28: 15-213 C Primer Session – 1/25/01

/* Allocate memory for an array of students. * Make sure to use sizeof when allocating memory for a struct. * Because of memory alignment issues, * struct may require more memory * than you think, so shouldn't hand calculate size. */ struct student *roster = (struct student *) malloc(MAX_STUDENTS * sizeof(struct student));

struct student tmpStudent;

/* Open text file with all of the student information * for reading. */ FILE *fid = fopen("students.txt", "r"); if(!fid) { printf("Error opening file for reading.\n"); return 1; }

Page 29: 15-213 C Primer Session – 1/25/01

/* FILL IN STRUCT ARRAY */ index = 0; while(fid && (index < MAX_STUDENTS)) { /* fscanf reads from the supplied stream 'fid‘ * under a controlled format * and assigns the converted values to the args provided. * Note: Each argument must be a pointer. * fscanf returns 0 when the format is exhausted * returns EOF if end of file or an error occurs * else returns number of items converted. */ n = fscanf(fid, "%s %s %s %d\n", tmpStudent.first, tmpStudent.last, tmpStudent.id, &(tmpStudent.age));

if (n == 0) { printf("Error scanning file.\n"); return 1; } if (n == EOF) break;

Page 30: 15-213 C Primer Session – 1/25/01

strncpy((*(roster + index)).first, tmpStudent.first, strlen(tmpStudent.first)); strncpy((*(roster + index)).last, tmpStudent.last, strlen(tmpStudent.last)); strncpy((*(roster + index)).id, tmpStudent.id, strlen(tmpStudent.id)); (*(roster + index)).age = tmpStudent.age;

/* Much easier way to do this copying */ memcpy((void *) (roster + index), (const void *) &tmpStudent, sizeof(struct student));

index++; }

Page 31: 15-213 C Primer Session – 1/25/01

/* PRINT OUT STRUCT ARRAY */ for(index = 0; index < MAX_STUDENTS; index++) { /* Notice here simpler way of accessing fields in struct. * '->' is a pre-processor shortcut for (*sptr).field */

printf("Student #%d: %s\t%s\t%s\t%d\n", index + 1, roster->last, roster->first, roster->id, roster->age); roster++; };

/* Clean-up */ free(roster); roster = NULL; fclose(fid); return 0;}