310 likes | 405 Views
Fundamentals of C. Program Structure Constants Variables Assignment Statements Standard Output Standard Input Math Functions Character Functions System Limitations Conditional Expressions Selection Statements Loop Structures. Simple Program Structure. /* ANSI-compliant comments */
E N D
Fundamentals of C • Program Structure • Constants • Variables • Assignment Statements • Standard Output • Standard Input • Math Functions • Character Functions • System Limitations • Conditional Expressions • Selection Statements • Loop Structures
Simple Program Structure /* ANSI-compliant comments */ // Comment to end of line - common but not ANSI-compliant prior to C99 #include <stdio.h> // printf() Standard header File #include “myinclude.h” // custom header file // Constant declaration - text replacement to comment of end of line #define PI (3.14159) int main(void) // default declaration for main() { // Variable Declarations int m,n,p=12; double area, r = 9.0, z = 9.2; // executable code here area = PI * r * r; return(0); // main() declared as type int - must return int. }
Constants Literal constants • Values literally appearing in the code. • Format determines how compiler interprets them. • Interpreted as an integer value: • 42 - Interpreted as an integer value. • 0x4F - Hexadecimal (0x prefix) - interpreted as an integer. • 042 - Octal (0 prefix - watch out!) - interpreted as an integer. • 84293L - Long integer - prevents compiler from truncating to int. • Interpreted as a floating point value: • 42. - Decimal point is sufficient. • 42.0 - But easy to miss - tacking on a zero is better. • 1e9 - Scientific notation #define statements • Convenient way to define symbolic constants. • Surrounding values with parentheses is good practice.
Variables A name associated with a memory location where a value can be stored. • Can consist of letters, digits, underscore characters - that’s it! • Leading character cannot be a digit. • Case sensitive - myvar, MYVAR, and MyVar are all different. • Only first 32 characters are significant (more in newest ANSI Standard) Variable types • Size and range system dependent - sizes below for Borland Turbo C/C++ V4.5 • integer types (can be prefixed with ‘unsigned’ to double positive range) • char - always one byte (but not always eight bits). One ASCII character. • int - two bytes (-32768 to +32767) • long (or long int) - four bytes (-2147483649 to +2147483648) • floating point types: • float - four bytes - ~5 sig figs, exponent +/- 38 • double - eight bytes - ~15 sig figs, exponent +/- 308 • long double - ten bytes - ~19 sig figs, exponent +/- 4932
Operators • Arithmetic Operators • Relational Operators • Logical Operators • Assignment Operators • Precedence • Associativity • Type Casts
Arithmetic Operators • * (Multiplication) • / (Division) • Integer Division if both operands are integers. • 17 / 5 = 3, not 3.4 - common, common error! • % (Modulo) • Remainder after Integer Division (17%5 = 2) • + (Addition) • - (Subtraction)
Relational Operators Evaluate to 0 if FALSE and 1 if TRUE • == (equality) (not = common, common mistake) • != (inequality) • > (greater than) • < (less than) • >= (greater than or equal to) • <= (less than or equal to) Complementary Pairs (always opposite result) • (==, !=), (>, <=), (<, >=)
Logical Operators Evaluate to 0 if FALSE and 1 if TRUE • ! (negation) (unary operator - operand to its right) • && (logical AND) (TRUE only if both operands are TRUE) • || (logical OR) (TRUE if either operand is TRUE) Logical Evaluation of Operands • Operand is FALSE if it is exactly equal to zero. • Operand is TRUE if it is ANYTHING other than zero. Guaranteed Short Circuiting • If result is known after evaluating left operand, right will not be evaluated. • Can by very useful in preventing errors. • Care must be exercised if there are side-effects in right operand. • (0 != x) && ( (y/x) > 1) • Useful: cannot result in division by zero. • (y >= x) || (j < k++) • Dangerous: Will not increment k if x < y!
Assignment Operators In expressions, evaluate to the value assigned. • x = y = 9 + (k = 12 + (x = j = 3)); // is valid code! Abbreviated Assignment Operators • *=, /=, %=, +=, -=, • k += x; is the same as k = k + x; Increment/Decrement Operators • k++, k-- (post-increment/decrement) • evaluates to original value of k in expressions. • ++k, --k (pre-increment/decrement) • evaluates to new value of k in expressions.
Precedence of Operators Largely follow familiar rules • (*, /, %) before (+, -) Use parentheses liberally • Easy to get trapped in subtleties. • Prevents the compiler from making your decisions for you! • Prevents common mistakes such as: • x = a+b / c; instead of x = (a+b)/c;
Associativity of Operators Determines order of evaluation when all else is equal. • Left Associativity: • x = y * z * w; => x = ( (y * z) * w); • Right Associativity: • x = y += z += w; => x = (y += (z += w)); Use parens liberally - don’t let the compiler decide!
Type Cast Operators Used to convert the representation of a value within an expression. • Has NO effect on the variable that is cast. • Operates on the value immediately to the right of the cast. • Use name of type in parens: • x = (double) j / (double) k; will force floating point division. • x = (double) (j/k); will still perform integer division. Compiler will do some casting automatically. • Only performed at points where necessary. • k = 12 + (14/20) + (7.5/3); • (7.5/3) => (7.5/3.0) = 2.5 (integer promoted to floating point) • (14/20) = 0 (no cast necessary, integer division used) • (12 + 0 + 2.5) => (12.0 + 0.0 + 2.5) = 14.5 (promotion) • k = 14.5 => k = 14 (demotion if k is an int)
Standard Output #include <stdio.h> • printf(“format string”, arg1, arg2, .... argN); // to the screen • fprintf(file_ptr, “format string”, arg1, arg2, .... argN); // to a file • sprintf(str_ptr, “format string”, arg1, arg2, .... argN); // to a string • each returns the number of characters printed. Format String • All but two characters printed verbatim. • % character used to format and output the next argument. • \ character used to print characters that can’t be typed directly. • Must be at least as many arguments as % specifiers.
% - printf() conversion specifiers Format: %[flags][width][.precision][modifier]type_character • All except type_character are optional. • Conversion specifier is everything from % sign to the first type_character. • [flags] - controls justification, leading spaces, sign, etc. • {-, +, , #, 0} • [width] - sets the minimum width of the field - may be longer. • [.precision] - sets the number of digits following the decimal point. • Usually used for floating points, but also affects character and integer types as well. • [modifier] - combines with type_character to determine argument type. • type_character - the basic type of that argument. • {c, d, e, E, f, g, G, i, o, p, s, u, x, X, %} In general, look up what you need. You will tend to remember the forms you use most often.
\ - printf() escape sequences Format: \(character) or \(number) • If a character follows the \, the action indicated by the character is performed. • \n - newline • \r - return w/o line feed. • \” - print double quote • \’ - print single quote (aka apostrophe) • \a - sound bell • \b - backspace • \\ - print backslash • \? - question mark • If a number follows the \, the ASCII character of the octal number is printed.
Standard Input #include <stdio.h> • scanf(“format string”, arg1, arg2, .... argN); // from the keyboard • scanf(file_ptr, “format string”, arg1, arg2, .... argN); // from a file • sscanf(str_ptr, “format string”, arg1, arg2, .... argN); // from a string • each returns the number of successful conversions. Format String • Literal characters in format string can be used to skip characters. • % conversion specifiers similar (but not identical) to printf(). • Arguments need to be memory locations where values will be stored. Big Time Caveat • If input does not adequately match format, results can be VERY unpredictable. • Many programmers avoid the use of scanf() at nearly any cost. • Use of fscanf() for file I/O is generally safe provided the file format is adequately constrained.
Common mistakes with scanf() Passing values instead of memory locations. • The scanf() function read values and store them at the memory locations you supply. k = 10; scanf(“%i”, k); • Tells scanf() to format the value as an integer and store it at location 10. • But the memory location for variable k is almost certainly not 10. • The address operator, &, returns the memory location of the specified variable. scanf(“%i”, &k); • Tells scanf() to format the value as an integer and store it at the memory address used for variable k. Using %lf for doubles. • printf() uses %lf for both floats and doubles because the compiler promotes all arguments of type float to double. • scanf() cannot due this. It must know which type the variable is so that the number and format of the bytes stored is correct.
Math functions #include <math.h> Approximately 30 function, most with a companion function for long ints. • trigonometric • sin(), cos(), tan() and their inverses. • sinh(), cosh(), tanh() but NOT their inverses (use trig relations) • atan2(y,x) - two argument version of atan() allowing four quadrant answer. • arguments and/or return values in radians - not degrees. • exponential/logorithmic • base e: exp(), log() • base 10: pow10(), log10 • other: sqrt(), pow(x, y) - returns x^y • absolute value • abs() - for integers only! common mistake • fabs() - for floating point values
ASCII Codes American Standard Code for Information Interchange - 7 bits (128 values) • Used to represent characters and certain codes used to control their display. • Originally developed for Teletypewriter applications. • Many nonstandard extensions exist to extend the code to 8 (or more) bits. • Codes <32 are control codes, some of which are no longer used. • Codes >=32 are printable characters (except 127 which is the DELETE control code. • ASCII 32 is the space character. In C, a character surrounded with single quotes is that character’s ASCII code. • ‘ ‘ = 32 • ‘0’ = 48 • ‘A’ = 65 • ‘a’ = 97 = ‘A’ + 32 = ‘A’ + ‘ ‘
Character functions #include <ctype.h> Character test functions • Return a logical value (0 or not-0) based on the properties of the character code. • isdigit(k) returns 0 unless ‘0’ <= k <= ‘9’ • isupper(k) returns 0 unless ‘A’ <= k <= ‘Z’ Character manipulation functions • Return a different code for some characters, otherwise return the value passed. • tolower(k) returns k+32 if isupper(k) is TRUE otherwise returns k.
System Limitations #include <limits.h> • Symbolic constants that define the limits of integer representations. • Examples: • INT_MAX Maximum value of an int • INT_MIN Minimum value of an int • ULONG_MAX Maximum value of an unsigned long int #include <float.h> • Symbolic constants that define the limits of floating point representations. • Examples: • DBL_MAX Largest representable value for a double. • DBL_MIN Smallest positive representable value for a double. • DBL_EPSILON Smallest value x such that 1+x is not equal to 1.
Selection Statements • Selectively choose one path of execution. • Based on the evaluation of a test. • Test outcome is either TRUE or FALSE. • FALSE if expression evaluates to ZERO. • TRUE if expression evaluates to ANYTHING else. • Three varieties of selection statements. • if()/else • switch() • ()? (conditional or ternary operator)
Conditional Expressions • (test) • May be ANY expression that evaluates to a value. • logical operator (!, ||, &&) • relational operator (==,!=),(>, <=), (<,>=) • assignment operator (equal to value assigned) • single variable (or constant) • function return value • Test outcome is either TRUE or FALSE. • FALSE if expression evaluates to ZERO - exactly. • TRUE if expression evaluates to ANYTHING else.
if() if()...else test? test? F F T T if_code if_code else_code if() and if()/else statements • Syntax if(test) { if_code; } else { else_code; }
x = ()?: test? F T x = if_expr x = else_expr ()? - conditional or ternary operator • Syntax x = (test)? if_expr:else_expr; • Shorthand version of if()/else
switch() statement (int_expr) must evaluate to an integer value at runtime. (int_constN) must evaluate to a unique integer constant at compile time. execution jumps to case where (int_constN == int_expr) is TRUE. break; terminates switch() execution. default case Optional. Executes only if NO other case executes. • Syntax switch(int_expr) { case int_const1: code1; break; case int_const2: code2; case int_const3: code3; break; default: code4; } • Compact way of writing certain types of complex but common if()/else blocks.
Testing for floating point equality if(x == y) // BAD!!! Only true if EXACTLY equal. Because a great deal of care went into how floating point values are represented, you can frequently get away with it - but unless you REALLY know what is going on and what is preventing disaster from visiting you, you are just being lucky! #DEFINE EPSILON (0.0001) if(EPSILON > fabs(x-y)) // GOOD!!! Looking for the difference between two values to be less than some small amount. Will work most of the time but EPSILON must be matched to the size of the values to be compared and the range of values can’t be too great. #DEFINE EPSILON (0.0001) if(fabs(EPSILON*y) > fabs(x-y)) // EVEN BETTER!!! Looking for two values to vary by less than a certain percentage. Comparison written so as to avoid potential division by zero during test.
Loop Structures Special case of Selection Statement • One branch eventually leads back to the original selection statement. • Permits a block of code to be executed repeatedly as long as some test condition is satisfied. C provides three different looping structures • while(), do/while(), for() • Only one is needed and any one is sufficient. • Different structures are better matches for the logic. • Using the “proper” one aides the programmer and anyone else reading the code. • The compiler doesn’t care and will often implement the code identically regardless of which structure is used.
ini_code test? F T loop_code inc_code next_code while() loop • Syntax ini_code // not part of loop while(test_expr) { loop_code; increment_code; } next_code; // not part of loop • Features • loop does not execute at all if test fails the first time.
ini_code loop_code inc_code T test? F next_code do/while() loop • Syntax ini_code // not part of loop do { loop_code; increment_code; } while(test_expr); next_code; // not part of loop • Features • loop will always execute at least once, even if test fails the first time.
ini_code test? F T loop_code inc_code next_code for() loop • Syntax for(ini_code; test_expr; inc_code) { loop_code; } next_code; // not part of loop • Features • Just a while() loop with the initialization and increment code formally incorporated into the syntax. • Can makes a cleaner divide between the loop logic and the housekeeping logic.