mith College CSC231 Bash Labs Week #10, 11, 12 Spring 2017 Introduction to C Dominique Thiébaut dthiebaut@smith.edu
Learning C in 4 Hours! D. Thiebaut
Dennis Ritchie 1969 to 1973 AT&T Bell Labs Close to Assembly Unix Standard Many languages based on C. (C++, Obj. C, C#) Many influenced by C (Java, Python, Perl)
C Lacks Exceptions Garbage collection OOP Polymorphism But
C Lacks Exceptions Garbage collection OOP Polymorphism But it is usually faster!
Good Reference Essential C, by Nick Parlante, Stanford U. http://cslibrary.stanford.edu/101/ EssentialC.pdf
Hello World! Library Strings Block-structured language main() #include <stdio.h> void main() { printf("\nhello World\n");
Hello World! Library getcopy C/hello.c Strings Block-structured language main() #include <stdio.h> void main() { printf("\nhello World\n");
gcc Gnu compiler man gcc for help Compiling on Aurora [~/handout]$ gcc hello.c [~/handout]$./a.out Hello World [~/handout]$ gcc -o hello hello.c [~/handout]$./hello Hello World
Files [~/handout]$ ls -l total 28 -rwx------ 1 352a 352a 6583 Oct 6 16:41 a.out* -rwx------ 1 352a 352a 6583 Oct 6 16:48 hello* -rw------- 1 352a 352a 66 Oct 6 16:41 hello.c -rw------- 1 352a 352a 67 Oct 6 16:39 hello.c~
Exercise Write your own Hello World! program Make it print something like: ************ * C Rocks! * ************
Good Reference on C Compiler http://www.gnu.org/software/gnu-cmanual/gnu-c-manual.html
Printing printf( string with %-operators, list of vars); %d int %f float %s string
Simple types Variables No strings! No booleans (only 0 for false and!0 for true) No classes, no objects! int -> integer variable short -> short integer long -> long integer float -> single precision real (floating point) variable double -> double precision real (floating point) variable char -> character variable (single byte)
Comments /* programname.c author This is the header */ #include <stdio.h> #include <string.h> void main() { // line comment print( Hello!\n" )
#include <stdio.h> #include <string.h> void main() { char hello[] = "hello"; char world[] = "world!"; char sentence[100] = ""; Strings strcpy( sentence, hello ); // sentence <- "hello" strcat( sentence, " " ); // sentence <- "hello " strcat( sentence, world ); // sentence <- "hello world!" printf( "sentence = %s\n", sentence ); [~/handout]$ gcc strings2.c [~/handout]$ a.out sentence = hello world! [~/handout]
Strings end with \0 #include <stdio.h> #include <string.h> void main() { char sentence[100] = "Hello world!"; printf( "sentence = %s\n", sentence ); sentence[5] = '\0'; printf( "sentence = %s\n", sentence ); ~/handout]$ a.out sentence = Hello world! sentence = Hello [~/handout]$
#include <stdio.h> #include <string.h> Exercise void main() { int a = 3; int b = 5; int c = 0; char firstname[] = "your first name here"; char lastname[] = "your last name here"; char fullname[100];... make the program store the sum of a and b into c, and then print your full name and the value in c. Also, make it output the number of characters in your full name; it must count the number of chars using a string function (use strlen).
For-Loops No int declaration!!! #include <stdio.h> void main() { int i; int sum = 0; // compute the sum of all the numbers from 1 to 100 for ( i=1; i<=100; i++ ) { sum += i; printf( "\nsum = %d\n\n", sum );
While-Loops #include <stdio.h> void main() { int i; int sum = 0; // compute the sum of all the numbers from 1 to 100 i = 1; while ( i<=100 ) { sum += i; // could have also used i++ i += 1; printf( "\nsum = %d\n\n", sum );
Infinite Loops #include <stdio.h> void main() { while ( 1 ) { printf( hello!\n ); #include <stdio.h> void main() { for ( ;; ) { printf( hello!\n );
Exercise Write a program that displays your full name underlined (line of dashes below). The underline length must be computed and the number of characters equal to the number of characters in your full name. Hints: strlen() returns # of chars man strlen
Exercise Write a program that displays a triangle of N lines of stars: * ** *** **** ***** Homework!
Symbolic Constants #include <stdio.h> #define NAME "Mickey" #define HEIGHT 5 #define YEARBORN 1928 void main() { printf( "%s is %d inches high, and was created in %d\n\n", NAME, HEIGHT, YEARBORN );
After preprocessing #include <stdio.h> Symbolic Constants #define NAME "Mickey" #define HEIGHT 5 #define YEARBORN 1928 void main() { printf( "%s is %d inches high, and was created in %d\n\n", "Mickey", 5, 1928 );
Conditionals #include <stdio.h> void main() { int a = 5; int b = 3; int c = 7; if ( a <= b && a <= c ) printf( "%d is the smallest\n\n", a ); else if ( b <= a && b <= c ) printf( "%d is the smallest\n\n", b ); else printf( "%d is the smallest\n\n", c );
Conditionals && and or! not
Conditionals (cont d) switch ( ordinal_expression ) { case ordinal_value: { //... break; case ordinal_value: { //... break; default: { //...
Conditionals (cont d) ints or chars, something countable switch ( ordinal_expression ) { case ordinal_value: { //... break; case ordinal_value: { //... break; default: { //...
Pointers
Concept float x = 6.5; float* px = &x;
Example: Initialize an Array #include <stdio.h> #define SIZE 10 int main() { float A[SIZE]; int i; Using indexing for ( i=0; i<size; i++ ) A[i] = i; for ( i=0; i<size; i++ ) printf( "A[%d] = %1.2f\n", i, A[i]);
Example: Initialize an Array #include <stdio.h> #define SIZE 10 void main() { float A[SIZE]; float* p; int i; p = A; for ( i=0; i<size; i++ ) { *p = i; p++; Using pointers p = A; for ( i=0; i<size; i++ ) { printf( "p=%p A[%d] = %1.2f *p = %1.2f\n", p, i, A[i], *p ); p = p + 1;
a.out p=0x7fff88d54560 A[0] = 0.00 *p = 0.00 p=0x7fff88d54564 A[1] = 1.00 *p = 1.00 p=0x7fff88d54568 A[2] = 2.00 *p = 2.00 p=0x7fff88d5456c A[3] = 3.00 *p = 3.00 p=0x7fff88d54570 A[4] = 4.00 *p = 4.00 p=0x7fff88d54574 A[5] = 5.00 *p = 5.00 p=0x7fff88d54578 A[6] = 6.00 *p = 6.00 p=0x7fff88d5457c A[7] = 7.00 *p = 7.00 p=0x7fff88d54580 A[8] = 8.00 *p = 8.00 p=0x7fff88d54584 A[9] = 9.00 *p = 9.00
Arrays TYPE v[dim]; TYPE* pv; pv = v;
Arrays The name of an array is a pointer to the first cell of the array. char name[dim]; name is the same as &(name[0])
* and & * has two meanings, depending on context Pointer to Contents of & means the address of
* and & int A[DIM]; int* p = A; // int pointer p int *q = &A[0]; // int pointer q *p = 3; // what p is pointing to gets 3 *(q+1) = 5; // what q is pointing to gets 5
Exercise #define DIM 10 int A[DIM]; int B[DIM]; int i; for ( i=0; i<dim; i++ ) A[i] = 13*i % 11; Write a C program that copies Array A into Array B using indexing, and then using pointers.
Exercise #define DIM 10 int A[DIM]; int i; for ( i=0; i<dim; i++ ) A[i] = 13*i % 11; Write a C program that finds the largest integer in Array A, using pointers.
Homework-Related Duffy Duck, (413) 585-2700, xxxxxxxx Mickey Mouse, (617) 123-4567, yyyyyyyyy Minnie Mouse, (617) 123-4567, zzzzzz zzz Bruno The Dog, (212) 678-9999, woof woof Exercise Given a list of names and personal information, blank out the phone numbers, leaving only the area code visible.
Functions Functions are always declared before they are used Functions can return values of simple types (int, char, floats), and even pointers. Functions get parameters of simple types, and pointers. Passing by value is automatic. Passing by reference requires passing a pointer.
#include <stdio.h> int sum( int a, int b ) { return a+b; Example 1 void main() { int x = 10; int y = 20; int z; z = sum( x, y ); printf( "z = %d\n", z ); z = sum( 3, 8 ); printf( "z = %d\n", z ); printf( "sum( 11, 22) = %d\n", sum( 11, 22 ) ); z = 30 z = 11 sum( 11, 22) = 33
#include <stdio.h> Example 2 (Incomplete code Add missing elements!) void sum2( int a, int b, int c ) { c = a+b; void main() { int x = 10; int y = 20; int z; Pass by Reference! sum2( x, y, z ); printf( "z = %d\n", z ); sum2( 3, 8, x ); printf( "x = %d\n", x ); z = 30 x = 11
Input: pass by reference! #include <stdio.h> void main() { int age; float mypi; char name[80]; printf( "Enter your name, please: " ); fgets( name, sizeof(name), stdin ); // will truncate to first // 80 chars entered printf( "Enter your age: " ); scanf( "%d", &age ); printf( "Enter your version of pi: " ); scanf( "%f", &mypi ); printf( "%s is %d years old, and thinks pi is %1.10f\n\n", name, age, mypi );
Input (cont d) a.out Enter your name, please: Mickey Enter your age: 21 Enter your version of pi: 3.14159 Mickey is 21 years old, and thinks pi is 3.1415901184
#include <stdio.h> #include <stdlib.h> #define N 10 Exercise // functions go here... void main() { int A[N] = { 3, 2, 1, 0, 6, 5, 9, 8, 7, -3 ; // your code goes here Write a C program (no functions) that finds the smallest, the largest, and computes the sum of all the ints in A. Write another program that does the same thing but uses functions. The results are passed back using return statements
Exercise Write another program that does the same thing but uses functions, and this time the results are passed back via a parameter passed by reference.
We Stopped Here Last Time https://farm1.staticflickr.com/44/145211107_f2020ec804_z.jpg
Trip Through Memory Lane
$9,958.95
28 lbs!
Dynamic Variables
Dynamic: think "new" in Java Memore Allocation for New Data Structure = malloc()
#include <stdio.h> #include <stdlib.h> void main() { int *A, N, i, smallest; Malloc printf( "How many ints? " ); scanf( "%d", &N ); A = (int *) malloc( N * sizeof( int ) ); for ( i=0; i<n; i++ ) { printf( "> " ); scanf( "%d", &(A[i]) ); smallest = A[0]; for ( i=1; i<n; i++ ) if ( A[i] < smallest ) smallest = A[i]; free( A ); printf( "The smallest = %d\n", smallest ); c/malloc1.c
Exercise Modify the previous program that computed the min and max of an array, but this time you allocate the array dynamically from the user input, i.e. ask the user for number of ints, then the ints. (use scanf("%d",&x) to get an int from keyboard into x) c/malloc1.c & smallestlargestsum2.c
sizeof() can be tricky
#include <stdio.h> #include <string.h> #include <stdlib.h> int main( int argc, char* argv[] ) { int A[] = { 1, 2, 3, 4, 5 ; int *B = (int *) malloc( 5 * sizeof( int ) ); int *p = A; char name[] = "Smith College"; int a = 3; float x = 3.14159; int i; sizeof () for ( i=0; i<5; i++ ) B[i] = i; printf( "sizeof(a) = %lu\n", sizeof( A ) ); printf( "sizeof(a[0]) = %lu\n", sizeof( A[0] ) ); printf( "sizeof(b) = %lu\n", sizeof( B ) ); printf( "sizeof(b[0]) = %lu\n", sizeof( B[0] ) ); printf( "sizeof(p) = %lu\n", sizeof( p ) ); printf( "sizeof(*p) = %lu\n", sizeof( *p ) ); printf( "sizeof(name) = %lu\n", sizeof( name ) ); printf( "strlen(name) = %lu\n", strlen( name ) ); printf( "sizeof(a) = %lu\n", sizeof( a ) ); printf( "sizeof(x) = %lu\n", sizeof( x ) ); return 0;
#include <stdio.h> #include <string.h> #include <stdlib.h> int main( int argc, char* argv[] ) { int A[] = { 1, 2, 3, 4, 5 ; int *B = (int *) malloc( 5 * sizeof( int ) ); int *p = A; char name[] = "Smith College"; int a = 3; float x = 3.14159; int i; sizeof () for ( i=0; i<5; i++ ) B[i] = i; printf( "sizeof(a) = %lu\n", sizeof( A ) ); printf( "sizeof(a[0]) = %lu\n", sizeof( A[0] ) ); printf( "sizeof(b) = %lu\n", sizeof( B ) ); printf( "sizeof(b[0]) = %lu\n", sizeof( B[0] ) ); printf( "sizeof(p) = %lu\n", sizeof( p ) ); printf( "sizeof(*p) = %lu\n", sizeof( *p ) ); printf( "sizeof(name) = %lu\n", sizeof( name ) ); printf( "strlen(name) = %lu\n", strlen( name ) ); printf( "sizeof(a) = %lu\n", sizeof( a ) ); printf( "sizeof(x) = %lu\n", sizeof( x ) ); return 0; sizeof(a) = 20 sizeof(a[0]) = 4 sizeof(b) = 8 sizeof(b[0]) = 4 sizeof(p) = 8 sizeof(*p) = 4 sizeof(name) = 14 strlen(name) = 13 sizeof(a) = 4 sizeof(x) = 4
#include <stdio.h> #include <string.h> #include <stdlib.h> int main( int argc, char* argv[] ) { int A[] = { 1, 2, 3, 4, 5 ; int *B = (int *) malloc( 5 * sizeof( int ) ); int *p = A; char name[] = "Smith College"; int a = 3; float x = 3.14159; int i; sizeof () Different! for ( i=0; i<5; i++ ) B[i] = i; printf( "sizeof(a) = %lu\n", sizeof( A ) ); printf( "sizeof(a[0]) = %lu\n", sizeof( A[0] ) ); printf( "sizeof(b) = %lu\n", sizeof( B ) ); printf( "sizeof(b[0]) = %lu\n", sizeof( B[0] ) ); printf( "sizeof(p) = %lu\n", sizeof( p ) ); printf( "sizeof(*p) = %lu\n", sizeof( *p ) ); printf( "sizeof(name) = %lu\n", sizeof( name ) ); printf( "strlen(name) = %lu\n", strlen( name ) ); printf( "sizeof(a) = %lu\n", sizeof( a ) ); printf( "sizeof(x) = %lu\n", sizeof( x ) ); return 0; sizeof(a) = 20 sizeof(a[0]) = 4 sizeof(b) = 8 sizeof(b[0]) = 4 sizeof(p) = 8 sizeof(*p) = 4 sizeof(name) = 14 strlen(name) = 13 sizeof(a) = 4 sizeof(x) = 4
File I/O output #include <stdio.h> void main() { FILE *fp; int i; char name[] = "Smith College"; fp = fopen("hello.txt", "w"); // open file for writing fprintf(fp, "\nhello " ); // write constant string fprintf(fp, "%s\n\n", name ); // write string fclose(fp); // close file
File I/O: Reading Text #include <stdio.h> void main() { FILE *fp; char line[80]; fp = fopen( "fgets2.c", "r" ); // open file for reading while (!feof( fp ) ) { fgets( line, 80, fp ); if ( feof( fp ) ) break; line[79] = '\0'; printf( "%s", line ); fclose( fp ); // while not eof // get at most 80 chars // if eof reached stop // truncate line to be safe // print it // close file c/readfile.c
File I/O: Input Numbers [~handout] cat fileofints.txt 4 1 2 3 4 5 6 7 8 9 10 11 12
File I/O: Reading Ints #include <stdio.h> void main() { FILE *fp; char line[80]; int N, n1, n2, n3; fp = fopen( "fileofints.txt", "r" ); // 1st number is # of lines // then 3 ints per line if ( feof( fp ) ) { printf( "Empty file!\n\n" ); return; // get the number of lines fscanf( fp, "%d", &N ); while (!feof( fp ) ) { fscanf( fp, "%d %d %d", &n1, &n2, &n3 ); if ( feof( fp ) ) break; printf( "%d, %d, %d\n", n1, n2, n3 ); fclose( fp ); c/readfilenumbers.c
File I/O: Reading Ints [~handout] a.out 1, 2, 3 4, 5, 6 7, 8, 9 10, 11, 12
At the Bash prompt type: cat > data.txt 4 10 1 2 3 ^D Exercise Write a program that reads the file data.txt, which has the number of ints in contains on the first line, then one int per line for the rest of the file. Your program must use a dynamically created array to store the numbers, and find the min and max of the array, and print them.
Function Prototypes and Multiple-File Projects
Original Program #include <stdio.h> #include <stdlib.h> #define N 10 int smallest( int* A ) { int i, min = A[0]; for (i=0; i<n; i++ ) if (A[i]<min ) min=a[i]; return min; void largest( int A[], int *max ) { int i; *max = A[0]; for (i=0; i<n; i++ ) if (A[i]>*max ) *max=a[i]; void addition( int A[], int *x ) { int i, sum=0; for (i=0; i<n; i++ ) sum +=A[i]; *x = sum; // functions go here... void main() { int A[N] = { 3, 2, 1, 0, 6, 5, 9,8, 7 ; int min, max, sum; min = smallest( A ); largest( A, &max ); addition( A, &sum ); printf( "%d %d %d\n", min, max, sum );
myfuncs.h #ifndef MYFUNCS_H #define MYFUNCS_H // prototypes int smallest( int* A, int N ); void largest( int A[], int N, int *max ); void addition( int A[], int N, int *x ); #endif myfuncs.c #include "myfuncs.h" int smallest( int* A, int N ) { int i, min = A[0]; for (i=0; i<n; i++ ) if (A[i]<min ) min=a[i]; return min; smallestlargestsum3.c #include <stdio.h> #include <stdlib.h> #include "myfuncs.h" #define N 10 void main() { int A[N] = { 3, 2, 1, 0, 6, 5, 9,8, 7 ; int min, max, sum; min = smallest( A, N ); largest( A, N, &max ); addition( A, N, &sum ); void largest( int A[], int N, int *max ) { int i; *max = A[0]; for (i=0; i<n; i++ ) if (A[i]>*max ) *max=a[i]; printf( "%d %d %d\n", min, max, sum ); void addition( int A[], int N, int *x ) { int i, sum=0; for (i=0; i<n; i++ ) sum +=A[i]; *x = sum;
myfuncs.h #ifndef MYFUNCS_H #define MYFUNCS_H // prototypes int smallest( int* A, int N ); void largest( int A[], int N, int *max ); void addition( int A[], int N, int *x ); #endif myfuncs.c #include "myfuncs.h" int smallest( int* A, int N ) { int i, min = A[0]; for (i=0; i<n; i++ ) if (A[i]<min ) min=a[i]; return min; void largest( int A[], int N, int *max ) { int i; *max = A[0]; for (i=0; i<n; i++ ) if (A[i]>*max ) *max=a[i]; void addition( int A[], int N, int *x ) { int i, sum=0; for (i=0; i<n; i++ ) sum +=A[i]; *x = sum; smallestlargestsum3.c #include <stdio.h> #include <stdlib.h> #include "myfuncs.h" #define N 10 void main() { int A[N] = { 3, 2, 1, 0, 6, 5, 9,8, 7 ; int min, max, sum; min = smallest( A, N ); largest( A, N, &max ); addition( A, N, &sum ); printf( "%d %d %d\n", min, max, sum ); 231b@aurora ~/handout/c $ gcc -c myfuncs.c 231b@aurora ~/handout/c $ gcc -o smallestlargestsum3 smallestlargestsum3.c myfuncs.o 231b@aurora ~/handout/c $./smallestlargestsum3 0 9 41 231b@aurora ~/handout/c $