C programming Intro to syntax & basic operations
Example 1: simple calculation with I/O
Program, line by line Line 1: preprocessor directive; used to incorporate code from existing library not actually considered part of the C program itself Syntax: #include <name of library>
Program, line by line Line 3: heading for main function Most C instructions take place within functions Syntax for function definition: data_type name (argument list) { /* instructions */ } Program execution begins with first statement in main function
Program, line by line Lines 9-11: data declaration statements set aside memory to hold data items line 9 declares a variable that can hold an integer value lines 10 & 11 declare integer constants
Program, line by line Lines 14-16: input & output statements printf: function that sends output to the screen scanf: function that reads input from the keyboard both types of statements are function calls; general syntax for a function call is: function_name (0 or more arguments)
Program, line by line Line 19: return statement Almost always the last statement in a function (we'll see a few exceptions along the way) Indicates that operation of function should cease If associated with a value, indicates the result of the function (in the case of main, return 0 just means this program ended normally)
Miscellaneous Elements Comments: Descriptive prose written for the human reader Start with /* and end with */ Can appear anywhere in a program Cannot be nested
Miscellaneous Elements White space Blank areas around text Can be placed anywhere, or left out, as long as: words and string literals aren't broken up and necessary symbols are in place; examples: Confusing, but still syntactically correct: #include <stdio.h> int main ( ) {printf ( Isn\'t this fun to read?\n ) ;return 0;} Readable, but wrong: #include <stdio.h> int main() { printf( Isn\'t this much easier?\n ); return 0; }
Basic output Prereq: include directive for stdio.h printf function: Takes at least one argument, a string literal (set of characters surrounded by double quotation marks) First argument may include: special characters, like \n (used to indicate an end-of-line character action of the Enter key) format specifiers, like %d (used as placeholder for an integer value to be specified later) If format specifier(s) included, additional argument(s) required: each argument represented by an expression must match data type specified (%d means int)
Basic input Also requires stdio.h scanf function: Takes a minimum of 2 arguments; IMHO best practice is 2 and only 2! First argument: format specifier Second argument: address of variable where value is to be stored ('&' character followed by variable name)
HAPPEN. ALL.THE. TIME. Programming has failure built into the process; learn to be comfortable with it, learn from mistakes Or at least don't let it freak you out. Errors
Two Types of Errors Syntax: violating rules of the programming language Semantic: code that is grammatically correct, but doesn't mean what you want it to mean Above excerpted from 15 Grammar Goofs That Make You Look Silly by Brian Clark (http://www.copyblogger.com/grammar-goofs/) Quote below attributed (wrongly!) to Alan Greenspan: I know you think you understand what you thought I said but I'm not sure you realize that what you heard is not what I meant
Syntax errors Leaving out characters, such as semicolons, brackets, parentheses, quote marks, commas Misspelling words includes what we normally think of as spelling, but also using uppercase character where lowercase should be, vice versa Adding extra characters where they don't belong (brackets or parentheses, often))
Syntax errors The good news: compiler catches them The bad news: % $#@!!compiler catches them! - & your code won't run until you fix them
Semantic errors Code compiles & runs, but produces bad results: program crashes (nasty, but at least you're alerted to the problem) results are wrong in some more subtle way: Miscalculation use of uninitialized variables
Variables, Data Types, & Expressions Variable: Named memory location for data storage As the name implies, value can be changed Characteristics: unique name (identifier) data type (determines amount of memory required & what can be stored there) Constant: just like a variable, except can't be changed once initial value given
Declaration Variable must be declared before it can be used Syntax: datatype name; /* or */ datatype name1, name2, name3; In C, variable declaration: sets aside a certain amount of memory (as much as is needed for specified data type) associates value stored there with name Caution: memory is not usually empty! Important to initialize variable before you use it in an expression
Initialization Means assigning a value to a variable Typically accomplished via an assignment statement (though can be done through input)
Assignment Value represented by variable changes each time you assign a new expression to it Assignment is thus a destructive operation: saving a new value destroys the previous saved value (unless you saved it somewhere else)
Example #include <stdio.h> int main () { int x; /* could be anything - let's prove it! */ printf("x=%d\n", x); /* OK, now let's assign a value */ x = 4; printf("x=%d\n", x); /* And now let's prove that assignment is NOT a test for equality: */ x = x * 2; printf("x=%d\n", x); return 0; }
Naming in C Name (identifier) must start with an alphabetic character (upper or lowercase) Can contain more letters, digits, and underscores (and nothing else) Cannot use words already part of the language like int, const, return, void Should not use words common in programs like main, printf, scanf, include
Naming in EGR-167 Variable (& constant) names should reflect their purpose Good examples: int hourpay; const int HOURS = 40; Bad example: int x;
Naming in EGR-167 General style principles: Use ALL UPPERCASE for constant names Use mixed case (start letter should be lowercase) for everything else
Data Types in C From the computer's point of view, the data type represents: how much memory is needed by a variable (or constant) how the bits in the memory space should be interpreted Data representation applet: http://math.hws.edu/tmcm/java/datareps/index.html From the programmer's point of view, data type represents what kind of value we can store in a given location
Whole number representation Most commonly used type for whole number representation is int (short for integer) Uses binary notation to represent number for most numbers, this is many more digits than required for decimal representation of same number
Whole number representation This means that the magnitude of a number is limited by the amount of memory allocated for a 32-bit integer, the range of possible values is -231.. 231 1 Consequence: adding 1 to 2 31 1 will give you -231, and subtracting 5 from -231 will give you 231 4! These phenomena are known as integer overflow and underflow, and can show up as semantic errors in your programs
Whole number representation Other data types for integers include short, long, and long long Each of these is specified to be either smaller or larger (in number of bits) than int the more bits you have, the greater the range of magnitude still subject to over/underflow
Whole number representation All of the integer types have an unsigned variant use when only positive numbers are appropriate range for typical (32-bit) int is 0.. 232 still subject to over/underflow, but won't go negative (will go to 0, in the case of overflow)
Real number representation Like integers, real numbers use binary representation, but the bits are interpreted not as whole numbers, but as approximations of real numbers Note: the exact same set of bits can be interpreted in radically different ways, depending on the data type! Number of bits allocated to each number determines both magnitude (as was seen with integers) and precision of number
Real number representation Use a form of scientific notation, or floatingpoint notation Example: the value 254.983 could also be represented as: 2.54983 x 102 or 25498.3 x 10-2 The former is the standard for scientific notation, and a variation of this is standard in C Depending on the circumstances, the number would likely be displayed as either 254.983 or 2.54983e2
Real number representation Three data types: float (short for floating-point number) double (short for double-precision floating-point number) long double (like a double, but even bigger) Most programmers just use double
Floating-point errors Although not subject to under/overflow problems like int, real numbers have problems of their own on computers Memory space is limited not all real numbers are finite consider π for example, or even 1/3 numbers with finite representations in decimal form may be infinitely repeating in binary form: this is true of 1/10, for example Approximation errors can propagate themselves over several calculations
Error propagation example Multiplier Multiplicand 14-bit product Actual product Error 1000.001 0.11101000 1110.1001 14.7784 1.46% (16.125) (0.90625) (14.5625) 1110.1001 0.11101000 1101.0011 13.4483 1.94% (14.5625) (13.1885) 1101.0011 0.11101000 1011.1111 12.2380 2.46% (13.1885) (11.9375) 1011.1111 0.11101000 1010.1101 11.1366 2.91% (11.9375) (10.8125) 1010.1101 0.11101000 1001.1100 10.1343 3.79% (10.8125) (9.75) 1001.1100 0.11101000 1000.1101 8.3922 4.44% (9.75) (8.8125)
Characters and Strings Character: a single character, represented in memory as an 8-bit number Uses ASCII code to represent characters Data type char can be used to declare variables to hold these values Literal value represented by a single character (or an escaped character) in single quotation marks Examples: 'a' '4' '\n'
Characters and Strings String literal: as we have previously seen, a set of characters enclosed in double quotation marks is called a string literal string: 0 or more characters strung together literal: the set of characters IS the value of the string C doesn't contain a built-in data type for representing strings but: can declare a collection of characters called a char array and store a string in that structure many C library functions have built-in support for treating char arrays as strings
Expressions Simplest definition: set of symbols that represents a value every value has a data type so every expression has a data type Examples: 2 is an int expression 2.0 is a double expression '2' is a char expression 2 is a string expression
Expressions Literal values (even strings have these, even though there is no string data type per se) Variables & constants (represent the value assigned) Function calls (sometimes more on this later) Compound expressions involving any/all of the above, in combination with operators
Arithmetic & C C has four basic operators for real-number arithmetic, and five for integer arithmetic Floating-point operators: *, /, +, - multiplicative operators take precedence over additive operators no precedence except position/parentheses among operators of same variety Integer operators: *, /, %, +, -
Wait what? %? Form of division name of operator is modulus Result of operation is remainder from division of integers
Integer division & modulus To understand this best, forget everything you have learned about division since about the 4th or 5th grade Well, don't forget it completely, since floatingpoint division still works as you'd expect; if you divide a double value by another double value, you'll get a double result Extend this thought to integers if you divide an int by an int, you'll get an int result
Examples 4.0 / 2.0 produces 2.0 4/2 produces 2 5.0 / 2.0 produces 2.5 5/2 produces 2 5%2 produces 1 4%2 produces 0 2%5 produces 2
Mixed-type expressions Expressions involving only int or only double values will produce int and double results, respectively When both data types are involved in an expression, the result will be of the more precise type double, in other words
Assigning incompatible values to variables C is considered a weakly-typed language can assign expressions of wrong data type to almost any variable if conversion is possible, it will be done (but not always in desirable ways) Example: int n = 8.9; /* n will get 8 */ double nn = n; /* nn will get 8.0 fractional part gone forever! */
Type casting Conversion of a value from one data type to another via assignment (as in the previous example) is called an implicit cast Can perform same operation explicitly by placing the desired data type in parentheses in front of the expression you wish to convert
Type casting Examples: int n = (int)(5.0 * 3.5); /* n = 17 */ n = (int)(5.0 * 3.5 +.5); /* n = 18 */ double nn = (double)(2 / 3); /* nn = 0.0 */ nn = (double)2 / 3; /* nn =.666666666667 */