Intermediate Programming, Spring 2017*

Similar documents
Intermediate Programming, Spring 2017*

Intermediate Programming, Spring 2017*

Intermediate Programming, Spring 2017*

cs3157: another C lecture (mon-21-feb-2005) C pre-processor (3).

Topic 6: A Quick Intro To C

CSci 4061 Introduction to Operating Systems. Programs in C/Unix

Deep C. Multifile projects Getting it running Data types Typecasting Memory management Pointers. CS-343 Operating Systems

Computer Labs: Debugging

Princeton University. Testing. Computer Science 217: Introduction to Programming Systems

Basic C Programming. Bin Li Assistant Professor Dept. of Electrical, Computer and Biomedical Engineering University of Rhode Island

Intermediate Programming, Spring 2017*

Intermediate Programming, Spring 2017*

Kurt Schmidt. October 30, 2018

CSCI-243 Exam 1 Review February 22, 2015 Presented by the RIT Computer Science Community

Hello, World! in C. Johann Myrkraverk Oskarsson October 23, The Quintessential Example Program 1. I Printing Text 2. II The Main Function 3

Basic C Programming (2) Bin Li Assistant Professor Dept. of Electrical, Computer and Biomedical Engineering University of Rhode Island

Intermediate Programming, Spring 2017*

C Review. MaxMSP Developers Workshop Summer 2009 CNMAT

PRINCIPLES OF OPERATING SYSTEMS

CS3157: Advanced Programming. Outline

Programming for Engineers C Preprocessor

OBJECT ORIENTED PROGRAMMING USING C++

A Fast Review of C Essentials Part II

Lab Exam 1 D [1 mark] Give an example of a sample input which would make the function

Formal Methods for C

Chapter 7: Preprocessing Directives

EXTERNAL TESTING. Princeton University Computer Science 217: Introduction to Programming Systems. Why Test? Testing. Why Test? Why Test?

Intermediate Programming, Spring 2017*

Robust Programming + Testing, Profiling, & Instrumentation

Topic 6: A Quick Intro To C. Reading. "goto Considered Harmful" History

Intermediate Programming, Spring 2017*

Final C Details. CSE 333 Autumn 2018

Midterm Exam Nov 8th, COMS W3157 Advanced Programming Columbia University Fall Instructor: Jae Woo Lee.

Tutorial 1: Introduction to C Computer Architecture and Systems Programming ( )

High-performance computing and programming Intro to C on Unix/Linux. Uppsala universitet

Compiler Theory. (GCC the GNU Compiler Collection) Sandro Spina 2009

Slide Set 5. for ENCM 339 Fall Steve Norman, PhD, PEng. Electrical & Computer Engineering Schulich School of Engineering University of Calgary

CS 326 Operating Systems C Programming. Greg Benson Department of Computer Science University of San Francisco

CSCI-243 Exam 2 Review February 22, 2015 Presented by the RIT Computer Science Community

CSE 333 Midterm Exam Sample Solution 7/28/14

COMsW Introduction to Computer Programming in C

Ricardo Rocha. Department of Computer Science Faculty of Sciences University of Porto

CSC209H Lecture 3. Dan Zingaro. January 21, 2015

Intermediate Programming, Spring Misha Kazhdan

Conditional Compilation

NEXT SET OF SLIDES FROM DENNIS FREY S FALL 2011 CMSC313.

1. We have a code sequence that is potentially executed twice.

Agenda. Components of a Computer. Computer Memory Type Name Addr Value. Pointer Type. Pointers. CS 61C: Great Ideas in Computer Architecture

Practical C Issues:! Preprocessor Directives, Multi-file Development, Makefiles. CS449 Fall 2017

COMP322 - Introduction to C++ Lecture 02 - Basics of C++

Introduction to Programming in C Department of Computer Science and Engineering. Lecture No. #54. Organizing Code in multiple files

CS 61C: Great Ideas in Computer Architecture. Lecture 3: Pointers. Krste Asanović & Randy Katz

Intermediate Programming, Spring 2017*

The C standard library

Rule 1-3: Use white space to break a function into paragraphs. Rule 1-5: Avoid very long statements. Use multiple shorter statements instead.

G52CPP C++ Programming Lecture 6. Dr Jason Atkin

Common Misunderstandings from Exam 1 Material

Intermediate Programming, Spring 2017*

#include. Practical C Issues: #define. #define Macros. Example. #if

CSE 303: Concepts and Tools for Software Development

#include <stdio.h> int main() { printf ("hello class\n"); return 0; }

For Your Amusement. Beware of bugs in the above code; I have only proved it correct, not tried it. Donald Knuth. Program Verification

Unit 4 Preprocessor Directives

Outline. Computer programming. Debugging. What is it. Debugging. Hints. Debugging

Final C Details. CSE 333 Winter Teaching Assistants: Alexey Beall Renshu Gu Harshita Neti David Porter Forrest Timour Soumya Vasisht

Lecture 03 Bits, Bytes and Data Types

Outline. Lecture 1 C primer What we will cover. If-statements and blocks in Python and C. Operators in Python and C

Programming. Projects with Multiple Files

Friday, September 16, Lab Notes. Command line arguments More pre-processor options Programs: Finish Program 1, begin Program 2 due next week

Princeton University Computer Science 217: Introduction to Programming Systems. Testing

Dynamic memory allocation (malloc)

G52CPP C++ Programming Lecture 8. Dr Jason Atkin

Dynamic memory allocation

mith College Computer Science CSC352 Week #7 Spring 2017 Introduction to C Dominique Thiébaut

CS 61C: Great Ideas in Computer Architecture. Lecture 3: Pointers. Bernhard Boser & Randy Katz

CS 0449 Sample Midterm

mith College Computer Science CSC231 Bash Labs Week #10, 11, 12 Spring 2017 Introduction to C Dominique Thiébaut

Gabriel Hugh Elkaim Spring CMPE 013/L: C Programming. CMPE 013/L: C Programming

CS113: Lecture 7. Topics: The C Preprocessor. I/O, Streams, Files

Computer Programming. The greatest gift you can give another is the purity of your attention. Richard Moss

CSE 333 Lecture 6 - data structures

From Java to C. Thanks to Randal E. Bryant and David R. O'Hallaron (Carnegie-Mellon University) for providing the basis for these slides

Recitation 2/18/2012

Testing and Debugging C Programming and Software Tools. N.C. State Department of Computer Science

Course organization. Part I: Introduction to C programming language (Week 1-12) Chapter 1: Overall Introduction (Week 1-4)

Lectures 5-6: Introduction to C

Binghamton University. CS-220 Spring C Debugging Basics. No relevant text

File I/O. Preprocessor Macros

C++ Tutorial AM 225. Dan Fortunato

Program Verification! Goals of this Lecture! Words from the Wise! Testing!

CS 261 Fall Mike Lam, Professor. Structs and I/O

CSE 333 Midterm Exam 2/12/16. Name UW ID#

CSE 374 Final Exam 3/15/17. Name UW ID#

Programming in C First meeting Tiina Niklander

cmps104a 2002q4 Assignment 2 Lexical Analyzer page 1

Lectures 5-6: Introduction to C

COSC Software Engineering. Lecture 16: Managing Memory Managers

Lecture 07 Debugging Programs with GDB

Programming in C week 1 meeting Tiina Niklander

Testing! The material for this lecture is drawn, in part, from! The Practice of Programming (Kernighan & Pike) Chapter 6!

Transcription:

600.120 Intermediate Programming, Spring 2017* Misha Kazhdan *Much of the code in these examples is not commented because it would otherwise not fit on the slides. This is bad coding practice in general and you should not follow my lead on this.

Outline Preprocessor directives Code correctness

Preprocessor directives Lines starting with # indicate preprocessor directives #include includes a file at the current location all the contents of stdio.h go here printf( hello world\n ); printf( hello world\n );

Preprocessor directives Lines starting with # indicate preprocessor directives #include #define associate a value to a preprocessor variable (no = sign) or just declare the existence of a preprocessor variable all the contents of stdio.h go here printf( %s: %f\n, 3.1415926, PI ); #define PI 3.1415926 #define PI_STR PI #define MISHA_DEBUG printf( %s: %f\n, PI_STR, PI );

Preprocessor directives Lines starting with # indicate preprocessor directives #include #define #undef undeclare the existence of a preprocessor variable #undef MISHA_DEBUG printf( %s: %f\n, PI_STR, PI );

Preprocessor directives Lines starting with # indicate preprocessor directives #include #define / #undef #if / #elif / #else / #endif Conditionally include the code all the contents of stdio.h go here printf( Using first code\n ); #define CODE 1 #if CODE==1 printf( Using first code\n ); #elif CODE==2 printf( Using second code\n ); #else // CODE!=1 && CODE!=2 fprintf( stderr, No code\n ); #endif // CODE

Preprocessor directives Lines starting with # indicate preprocessor directives #include #define / #undef #if / #elif / #else / #endif #ifdef / #else / #endif #ifndef / #else / #endif Conditionally include the code all the contents of stdio.h go here printf( Using first code\n ); #define MISHA_DEBUG #ifdef MISHA_DEBUG printf( debug mode ); #else //!MISHA_DEBUG printf( release mode\n ); #endif // MISHA_DEBUG

Preprocessor directives Lines starting with # indicate preprocessor directives #include #define / #undef #if / #elif / #else / #endif #ifdef / #else / #endif #ifndef / #else / #endif #error force a compiler error #undef GOOD_CODE #ifndef GOOD_CODE #error bad code #endif //!GOOD_CODE printf( hello\n ); >> gcc -std=c99 -pedantic -Wall -Wextra foo.c foo.c:6:2: error: #error "bad code\n"; #error "bad code\n"; ^~~~~ >>

Preprocessor directives Lines starting with # indicate preprocessor directives #include #define / #undef #if / #elif / #else / #endif #ifdef / #else / #endif #ifndef / #else / #endif #error And many more

Preprocessor directives Lines starting with # indicate preprocessor directives You can nest preprocessor directives all the contents of stdio.h go here printf( debugging 1\n ); #define MISHA_DEBUG #define DEBUG_MODE 1 #ifdef MISHA_DEBUG #if DEBUG_MODE==1 printf( debugging 1\n ); #else // DEBUG_MODE!=1 printf( unknown debug mode\n ); #endif #else //!MISHA_DEBUG printf( hello world ); #endif // MISHA_DEBUG

Preprocessor directives Lines starting with # indicate preprocessor directives You can nest preprocessor directives Can be very useful while working on code: You can work on new changes without discarding the old ones You can specify that different parts of the code should be activated / deactivated together It makes it hard to read the code Remove all the unnecessary directives (unused code) once you ve got the new version up and running

Outline Preprocessor directives Code correctness

Code correctness During execution, your code may end up in a bad state from which you cannot recover Blame the world: The assumptions about the state of the system are false Bad user input insufficient arguments int main( int argc, char* argv[] ) if( argc<2 ) fprintf( stderr, ) ; exit( 0 );

Code correctness During execution, your code may end up in a bad state from which you cannot recover Blame the world: The assumptions about the state of the system are false Bad user input: insufficient arguments file can t be accessed int main( int argc, char* argv[] ) if( argc<2 ) fprintf( stderr, ) ; exit(0); FILE* fp = fopen( argv[1], r ); if( fp==null ) fprintf( stderr, ), exit( 0 );

Code correctness During execution, your code may end up in a bad state from which you cannot recover Blame the world: The assumptions about the state of the system are false Bad user input insufficient arguments file can t be accessed wrong argument type / value int main( int argc, char* argv[] ) if( argc<2 ) fprintf( stderr, ) ; exit(0); int i = atoi( argv[1] ); if( i<=0 ) fprintf( stderr, ) ; exit( 0 );

Code correctness During execution, your code may end up in a bad state from which you cannot recover Blame the world: The assumptions about the state of the system are false Bad user input insufficient arguments file can t be accessed wrong argument type / value Bad system state insufficient memory int main( int argc, char* argv[] ) if( argc<2 ) fprintf( stderr, ) ; exit(0); int i = atoi( argv[1] ); if( i<=0 ) fprintf( stderr, ) ; exit( 0 ); char* str = malloc( i ); if(!str ) fprintf( stderr, ) ; exit( 0 );

Code correctness During execution, your code may end up in a bad state from which you cannot recover Blame the world: The assumptions about the state of the system are false Bad user input Bad system state Print out a meaningful error message and: from main: return with a failure (non-zero) value from a function: exit

Code correctness During execution, your code may end up in a bad state from which you cannot recover Blame the world: The assumptions about the state of the system are false Blame yourself: The code didn t do what it should have void sort_ints( int* arr, size_t sz ) int a[] = 11, 7, 9, 5, 8, 4, 2 ; sort_ints( a, sizeof(a) / sizeof(int) ); if( a[0]>a[1] )

Code correctness During execution, your code may end up in a bad state from which you cannot recover Blame the world: The assumptions about the state of the system are false Blame yourself: The code didn t do what it should have Include the assert.h header file assert the validity of a test If the argument is true, nothing happens Otherwise, the code aborts and a core dump file is generated #include <assert.h> void sort_ints( int* arr, size_t sz ) return; int a[] = 11, 7, 9, 5, 8, 4, 2 ; sort_ints( a, sizeof(a) / sizeof(int) ); assert( a[0]<a[1] ); >>./a.out a.out: foo.c:11: main: Assertion `a[0]<a[1]' failed.abort (cored dumped) >> You can use gdb to debug the core dump

Code correctness Note: This code tests if the first two elements are sorted #include <assert.h> void sort_ints( int* arr, size_t sz ) return; int a[] = 11, 7, 9, 5, 8, 4, 2 ; sort_ints( a, sizeof(a) / sizeof(int) ); assert( a[0]<a[1] );

Code correctness Note: This code tests if the first two elements are sorted Better code tests that all the elements are sorted #include <assert.h> void sort_ints( int* arr, size_t sz ) return; int a[] = 11, 7, 9, 5, 8, 4, 2 ; sort_ints( a, sizeof(a) / sizeof(int) ); assert( a[0]<a[1] ); #include <assert.h> void sort_ints( int* arr, size_t sz ) int issorted( const int * arr, size_t sz ) for( int i=0 ; i<sz-1 ; i++ ) if( arr[i]>arr[i+1] ) return 1; int a[] = 11, 7, 9, 5, 8, 4, 2 ; sort_ints( a, sizeof(a) / sizeof(int) ); assert( issorted( a, sizeof(a) / sizeof(int) );

Notes on assert assert is defined as a macro, not a function #include <assert.h> void sort_ints( int* arr, size_t sz ) int issorted( const int * arr, size_t sz ) for( int i=0 ; i<sz-1 ; i++ ) if( arr[i]>arr[i+1] ) return 1; int a[] = 11, 7, 9, 5, 8, 4, 2 ; sort_ints( a, sizeof(a) / sizeof(int) ); assert( issorted( a, sizeof(a) / sizeof(int) );

Notes on assert assert is defined as a macro, not a function Once our code is working we can stop the assertion by defining the preprocessor variable NDEBUG #define NDEBUG #include <assert.h> void sort_ints( int* arr, size_t sz ) int issorted( const int * arr, size_t sz ) for( int i=0 ; i<sz-1 ; i++ ) if( arr[i]>arr[i+1] ) return 1; int a[] = 11, 7, 9, 5, 8, 4, 2 ; sort_ints( a, sizeof(a) / sizeof(int) ); assert( issorted( a, sizeof(a) / sizeof(int) );

Notes on assert assert is defined as a macro, not a function Once our code is working we can stop the assertion by defining the preprocessor variable NDEBUG This removes the whole assertion clause so that the argument is not evaluated issorted doesn t get called so the code runs more quickly #define NDEBUG #include <assert.h> void sort_ints( int* arr, size_t sz ) int issorted( const int * arr, size_t sz ) for( int i=0 ; i<sz-1 ; i++ ) if( arr[i]>arr[i+1] ) return 1; int a[] = 11, 7, 9, 5, 8, 4, 2 ; sort_ints( a, sizeof(a) / sizeof(int) ); assert( issorted( a, sizeof(a) / sizeof(int) );

Notes on assert assert is defined as a macro, not a function Once our code is working we can stop the assertion by defining the preprocessor variable NDEBUG This removes the whole assertion clause so that the argument is not evaluated issorted doesn t get called so the code runs more quickly Beware: The argument of assert should not do something useful! #define NDEBUG #include <assert.h> void sort_ints( int* arr, size_t sz ) int issorted( const int * arr, size_t sz ) for( int i=0 ; i<sz-1 ; i++ ) if( arr[i]>arr[i+1] ) return 1; int sortandtest( int* arr, size_t sz ) sort( arr, sz ); return( issorted( arr, sz ) ); int a[] = 11, 7, 9, 5, 8, 4, 2 ; assert( sortandtest( a, sizeof(a) / sizeof(int) );

Testing Until now, our program testing has been applied to an entire program Run with prescribed input and check if the output matches what we expect This is called end-to-end testing Verifies that program will run as expected under real-world conditions End-to-end testing is important, but tracking down bugs this way gets more difficult as programs get larger and more complex It doesn t help identify where these are broken when the output is wrong

Unit testing IDEA: Test each unit, or module, of a program separately For each function we write, we create another function which tests it A test function is typically fairly simple, and just runs a number of tests on the subject function, one after another Tests typically consist of feeding the subject function a known input, and verifying that it returns the appropriate result Each input/desired output pair is called a test case Want numerous test cases, so passing all test cases is convincing evidence that subject function works correctly Test with a wide variety: good inputs, bad inputs, boundary/corner cases

Unit testing It s generally hard/impossible to prove that code is correct. Unit tests help convince us that our functions ( building blocks ) behave correctly, or else they help us locate errors quickly Useful for adapting /modifying code e.g. If function foo1 calls function foo2, we can check that changes to foo2 don t invalidate the functionality of foo1 Writing unit tests shouldn t be an afterthought; resulting code is often better when we test as we go (and it takes less time to write overall) It s turtles all the way down: We re still left with the problem of confirming that our unit tests are correct Hopefully they are simple enough that there is less of an opportunity for error.

Coding Session