MAE 4733 Notes1

download MAE 4733 Notes1

of 132

Transcript of MAE 4733 Notes1

  • 8/8/2019 MAE 4733 Notes1

    1/132

    C0-1

    INTRODUCTION TO PROGRAMMING IN C

    MAE 4733Mechatronics Design

    Gary E. Young

    Professor

    School of Mechanical and Aerospace Engineering

    Oklahoma State University

    Stillwater, Oklahoma

    G. E. Young 1990 - 1999

  • 8/8/2019 MAE 4733 Notes1

    2/132

    C1-1

    Why C?

    * A general purpose programming language

    * Small and compact

    * Powerful operators and control structures

    * Natural interface with operating system

    * Modular programming

    * Low Level operators for real-time applications

    * Portable

  • 8/8/2019 MAE 4733 Notes1

    3/132

    C1-2

    A First Program

    Programming process:

    EDIT - - -> COMPILE - - -> LINK - - -> EXECUTE

    EDIT -- put program into a text file.

    sea.c: (K&P, p. 6)

    Note: K&P denotes Kelley and Pohl, A Book on C,4th Edition, Addison Wesley Longman, 1998.

    #include

    int main(void)

    {

    printf("from sea to shining C\n");

    return 0;

    }

  • 8/8/2019 MAE 4733 Notes1

    4/132

    C1-3

    Note: Kernighan & Ritchie in their book: The C

    Programming Language (Prentice-Hall, 1

    st

    Ed. 1978,2nd Ed. 1988 (ANSI version), used the string

    "hello, world\n" in the printf() function.

    You may see references to this string in other

    texts.

    COMPILE and LINK -- The "cc" command can do both.

    cc sea.c

    EXECUTE -- Default executable file name is a.out.

    Command: a.out

    Output: from sea to shining C

  • 8/8/2019 MAE 4733 Notes1

    5/132

    C1-4

    Variables, Expressions, and Assignment (K&P, p. 11)

    /* The distance of a marathon in kilometers. */

    #include

    int main(void)

    {

    int miles, yards;

    float kilometers;

    miles = 26;yards = 385;

    kilometers = 1.609 * (miles + yards / 1760.0);

    printf("\nA marathon is %f kilometers.\n\n",

    kilometers);

    return 0;}

    The output of the program is

    A marathon is 42.185970 kilometers.

  • 8/8/2019 MAE 4733 Notes1

    6/132

    C1-5

    The Use of #define and #include (K&P, p. 13)

    The C compiler has a preprocessor built into it.

    Lines starting with a # are called preprocessing

    directives.

    #define LIMIT 100

    #define PI 3.14159

    After the preprocessor stage and before the compile

    stage, the following line

    x = 2.0 * PI + LIMIT;

    will look to the compiler like

    x = 2.0 * 3.14159 + 100;

    Capital letters (Caps) are used for defined parameters

    to make the program easier to read and debug for

    yourself and others.

  • 8/8/2019 MAE 4733 Notes1

    7/132

    C1-6

    #include is the same idea as #define only with lines of

    code to be substituted.

    #include "stdio.h"

    will insert the header file (hence the '.h' extension)

    stdio.h into this location.

    The use of "stdio.h" or controls how the

    operating system will look for this file. (You may have

    more than one file with this name and you must be

    careful to get the correct file.)

  • 8/8/2019 MAE 4733 Notes1

    8/132

    C1-7

    The Use of printf() and scanf()(K&P, p. 18)

    Both printf() and scanf() are passed arguments which can

    be thought of as control_string and other_arguments.

    Look at a previous example.

    printf("\nA marathon is %f kilometers.\n\n",kilometers);

    The control_string must be between double quotes.

    Here, the other_argument is the parameter to be printed.

    The control_string is like a format statement.

    The '%f' directs how the parameter is to be printed.

    The '\' in '\n' indicates that the following character(here, an 'n') is a special character.

    '\n' is interpreted as a carriage return (start a new

    line, left justified).

  • 8/8/2019 MAE 4733 Notes1

    9/132

    C1-8

    The following three lines will produce the same output

    (K&P, p. 18).

    printf("abc");

    printf("%s", "abc");

    printf("%c%c%c", 'a', 'b', 'c');

    printf() conversion characters

    c character

    d decimal integer

    e floating point number in scientific notation

    f floating point number

    g in e- or -f format, whichever is shorter

    s string (array of characters)

  • 8/8/2019 MAE 4733 Notes1

    10/132

    C1-9

    The other_arguments in the scanf() function are

    addresses of the variables.

    This will be confusing at first.

    scanf("%d", &x);

    will read from the standard input device (keyboard) a

    number, interpret it as a decimal integer (%d directive)

    and store it in a memory location associated with the

    variable 'x'.

    We don't know what the address of these variables are,so the '&' is an 'address of' operator and is used to

    find this information.

    Example:

    #include

    int main(void)

    {

  • 8/8/2019 MAE 4733 Notes1

    11/132

    C1-10

    int a,b,c;

    printf("%s","Enter two integers:");

    scanf("%d%d", &a, &b);

    c = a + b;

    printf("\n\nThe sum is %d\n",c);

    return 0;

    }

    scanf() conversion characters

    c character

    d decimal integer

    f floating point number (float)

    lf floating point number (double)

    s string (array of characters)

  • 8/8/2019 MAE 4733 Notes1

    12/132

    C1-11

    Flow of Control (K&P, p. 21)

    if, if-else, for, and while statements

    if(expression)

    statement

    Example: if(x == 0)sum = 1;

    if(expression)

    statement1

    elsestatement2

    Example: if(x == 0)sum = 1;

    elsesum = a + b;

    while(expression)

    statement

  • 8/8/2019 MAE 4733 Notes1

    13/132

    C1-12

    Example: while(i != 0)

    index = index + 1;

    for(expr1;expr2;expr3)

    statement

    equivalent to expr1;

    while(expr2) {

    statement

    expr3;

    }

    Example: for(i = 1; i

  • 8/8/2019 MAE 4733 Notes1

    14/132

    C1-13

    Functions (K&P, p. 29)

    Functions take arguments and return a value.

    These arguments and returned value must be declared.

    Example: double pow(double x, double y);

    The arguments x and y are doubles (long floats)

    and the pow function returns a double.

    Example: Find the maximum and minimum values of a set of

    numbers. (K&P, pp. 30 - 31)

    In file maxmin.c

    #include

    float maximum(float x, float y);

    float minimum(float x,float y);

    void prn_info(void);

  • 8/8/2019 MAE 4733 Notes1

    15/132

    C1-14

    int main(void)

    {

    int i, n;

    float max, min, x;

    prn_info();

    printf("Input n: ");

    scanf("%d", &n);

    printf("\nInput %d real numbers: ",n);

    scanf("%f", &x);

    max = min = x;

    for(i=2; i

  • 8/8/2019 MAE 4733 Notes1

    16/132

    C1-15

    float maximum(float x, float y)

    {

    if(x > y)

    return x;

    else

    return y;

    }

    float minimum(float x, float y)

    {

    if(x < y)

    return x;

    elsereturn y;

    }

    void prn_info(void)

    {

    printf("\n%s\n%s\n%s\n\n","This program reads an integer value for n, ",

    "and then processes n real numbers to find ",

    "max and min values.");

    }

  • 8/8/2019 MAE 4733 Notes1

    17/132

    C1-16

    Non-ANSI C used formal parameters in function

    declarations with no argument type checking.

    float minimum(),maximum();

    .

    .

    .

    float minimum(x,y)

    float x,y;

    {

    if(x

  • 8/8/2019 MAE 4733 Notes1

    18/132

    C1-17

    Arrays, Strings, and Pointers (K&P, p. 36)

    #include

    #define CLASS_SIZE 5

    int main(void)

    {

    int i,j,score[CLASS_SIZE], sum = 0, tmp;

    printf("Input %d scores: ",CLASS_SIZE);

    for(i=0; i < CLASS_SIZE; ++i) {

    scanf("%d",&score[i]);

    sum += score[i];}

    for(i=0; i < CLASS_SIZE - 1; ++i)

    for(j=CLASS_SIZE - 1; j > i; --j)

    if(score[j-1] < score[j]) {tmp = score[j-1];

    score[j-1] = score[j];

    score[j] = tmp;

    }

  • 8/8/2019 MAE 4733 Notes1

    19/132

    C1-18

    printf("Ordered scores:\n\n");

    for(i=0; i < CLASS_SIZE; ++i)

    printf(" score[%d] =%5d\n",i,score[i]);

    printf("\n%18d%s\n%18.1f%s\n\n",

    sum," is the sum of all the scores",

    (double) sum/CLASS_SIZE," is the average");

    return 0;

    }

    Strings (K&P, p. 39)

    A string is an array of characters.

    A string is terminated by the null character '\0'.

  • 8/8/2019 MAE 4733 Notes1

    20/132

    C1-19

    Example: nice_day.c in (K&P, p. 39) modified.

    #include

    #include

    #define MAXSTRING 100

    int main(void)

    {char c, name[MAXSTRING];

    int i, sum = 0;

    printf("\nHi! What is your name? ");

    for(i = 0; (c=getchar()) != '\n'; ++i) {name[i] = c;

    sum += 1;

    }

    name[i] = '\0' /* append '\0' to terminate string */

    printf("\n%s%s%s","Nice to meet you ", name, ".");

    printf("\nYou have %d letters in your name\n", sum);

    return 0;

    }

  • 8/8/2019 MAE 4733 Notes1

    21/132

    C1-20

    Pointers (K&P, p. 42)

    A pointer is an address of an object in memory.

    They are used because of their efficiency.

    In function calls, a pointer can be used instead of

    copying an array of data. Only one address is required!

    An array name is a pointer to the first element in the

    array by definition.

    Example: file abc.c (K&P, p. 43)

    #include

    #include

    #define MAXSTRING 100

    int main(void)

    {

    char c = 'a', *p, s[MAXSTRING];

  • 8/8/2019 MAE 4733 Notes1

    22/132

    C1-21

    p = &c;

    printf("%c%c%c ", *p, *p + 1, *p + 2);

    strcpy(s,"ABC");

    printf("%s %c%c%s\n", s, *s + 6, *s + 7, s+1);

    strcpy(s, "she sells sea shells by the seashore");

    p = s + 14;

    for(; *p != '\0'; ++p) {

    if(*p == 'e')*p = 'E';

    if(*p == ' ')

    *p = '\n';

    }

    printf("%s\n", s);return 0;

    }

    The output of this program is

    abc ABC GHBCshe sells sea shElls

    by

    thE

    sEashorE

  • 8/8/2019 MAE 4733 Notes1

    23/132

    C1-22

    Files (K&P, p. 47)

    scanf() and printf() read and write to the standard

    input/output devices (keyboard and monitor screen).

    To read from and write to other devices use file pointers.

    Example:

    #include

    int main(void)

    {FILE *ifp, *ofp; /* FILE is defined in stdio.h */

    /* ifp is an input file pointer */

    /* ofp is an output file pointer */

    . . .

    ifp = fopen("in_file.dat", "r"); /* open for reading */ofp = fopen("out_file.dat", "w"); /* open for writing */

    . . .

  • 8/8/2019 MAE 4733 Notes1

    24/132

    C1-23

    while(fscanf(ifp, "%d", &a) == 1)

    sum += a;

    fprintf(ofp, "The sum is %d.\n", sum);

    . . .

    while((c = getc(ifp)) != EOF) {do something}

    . . . /* EOF stands for End of File */

    /* Where might this be defined? */

    fclose(ifp); /* Be sure to close your files */

    fclose(ofp); /* before exiting your program. */

    Three modes in which to open a file include the following.

    "r" open text file for reading

    "w" open text file for writing"a" open text file for appending

    For a more complete list, see (K&P, p. 506).

  • 8/8/2019 MAE 4733 Notes1

    25/132

    C1-24

    * Given a program in a file called x.c:

    how do you compile it?

    how do you run it?

    * What are the essential parts of a C program?

    * How would you declare i to be an integer and set

    it to the value 10 all in one statement?

    * What is wrong with the following statements?

    printf("hello/n");

    b = a(3);

    int i, c[10];

    for(i=0; i

  • 8/8/2019 MAE 4733 Notes1

    26/132

    C2-1

    Keywords

    auto do goto signed unsigned

    break double if sizeof void

    case else int static volatile

    char enum long struct while

    const extern register switch

    continue float return typedef

    default for short union

    Some implementations may have additional keywords,

    e.g., asm for in-line assembly language code.

  • 8/8/2019 MAE 4733 Notes1

    27/132

    C2-2

    Identifiers (K&P, p. 78)

    Identifiers are made up of letters (first character is amust), numbers, and the underscore character.

    No special characters are acceptable in the identifier.

    Different compilers and systems will have differentconstraints on the number of recognizable characters.

    Examples of acceptable identifiers:

    k, _id, thisisvariable1, this_is_variable_1

    Variables such as _sin and _id are usually used forsystem variables and should be avoided unless you arewriting a compiler or operating system.

    Examples of non-acceptable identifiers:

    not#me, 101_south, -plus, $$2u

  • 8/8/2019 MAE 4733 Notes1

    28/132

    C2-3

    Increment and Decrement Operators

    (++ and --)

    ++ means "increment": adds 1 to a variable.

    -- means "decrement": subtracts 1 from a variable.

    "++i" increments i, THEN uses i's NEW value

    "i++" uses i's OLD value, THEN increments i

    preincrement and postincrement operators

    --i; predecrement; i--; postdecrement

    So now you can explain the origin of 'C++'.

  • 8/8/2019 MAE 4733 Notes1

    29/132

    C2-4

    What's the difference?

    n = 3; n = 3;vs.

    x = n++; x = ++n;

    Example: (K&P, p.85)

    int a,b,c=0;

    a = ++c;

    b = c++;

    printf("%d %d %d\n",a,b,++c);

    /* What gets printed? *//* Could it be 1 1 3? */

  • 8/8/2019 MAE 4733 Notes1

    30/132

    C2-5

    ++i; and i++; are equivalent to i = i + 1;

    but increment operators produce faster code.

    Assignment Operators

    =

    += -= *= /= %=

    >>=

  • 8/8/2019 MAE 4733 Notes1

    31/132

    C2-6

    * What happens in the following piece of code?

    while(c = ' ' || c == '\t' || c == '\n')

    c = getc(fp);

    /* getc(fp) gets next character from file */

    /* pointed to by file pointer fp */

    * while(1); /* same as for(;;); */

    * What happens here?

    if(x[i] > big);big = x[i];

  • 8/8/2019 MAE 4733 Notes1

    32/132

    C2-7

    * What gets printed on your system?

    void main(void)

    {

    char c;

    printf("sizeof(c) = %d\n",sizeof(c));

    printf("sizeof('a') = %d\n",sizeof('a'));

    printf("sizeof(c='a') = %d\n",sizeof(c='a');

    } /* sizeof(x) returns size of 'x' in bytes */

  • 8/8/2019 MAE 4733 Notes1

    33/132

    C3-1

    Fundamental Data Types

    char signed char unsigned char

    short int long

    unsigned short unsigned unsigned long

    float double long double

  • 8/8/2019 MAE 4733 Notes1

    34/132

    C3-2

    Characters

    * "char" is an integer data type.

    * char values may be interpreted as integer numbers.

    * char values may be interpreted as ASCII codes

    (See Appendix D of K&P, pp. 703 - 704)

    char c = 'a';

    printf("%c",c); /* a is printed */

    printf("%d",c); /* 97 is printed */

    printf("%c%c%c", c, c+1, c+2); /* abc is printed*/

    What is the result of:

    char x;

    int y;

    x = 'r' + 1;

    y = x + 1;

    printf("x = %d\nx = %c\nx = %x\n

    y = %d\n",x,x,x,y);

  • 8/8/2019 MAE 4733 Notes1

    35/132

    C3-3

    The escape character is used to represent special

    characters. (See K&P, p. 113)

    escape character is a backslash: \

    What does this do:

    printf("\n\n\t\007You goofed!!");

    Hint: Octal numbers start with the escape

    sequence \0. /* '0' not capital 'o' */

    Hexadecimal numbers start with theescape sequence \x or \X.

    Decimal numbers do not start with an

    escape sequence.

    To clear the screen on an ANSI terminal:

    write(1, "\033[2J", 4);

  • 8/8/2019 MAE 4733 Notes1

    36/132

    C3-4

    * In addition to the provided data types, the Clanguage allows explicit association of a data type

    with an identifier.

    * This mechanism is called the typedef.

    * Used most often when defining structures.

    (K&P, Chapter 9).

    Examples:

    typedef char * string;

    typedef int INCHES, FEET, YARDS;

    typedef float vector[10];

    INCHES length, width;

    string s1 = "abc", s2 = "xyz";

    vector x;

  • 8/8/2019 MAE 4733 Notes1

    37/132

    C3-5

    Mathematical Functions

    Functions such as

    sqrt() pow() exp() log() sin() cos() tan()

    appear in a special math library.

    To link to the math library when compiling:

    cc program.c -lm (Unix)

    Standard definitions are in themath.h header file.

  • 8/8/2019 MAE 4733 Notes1

    38/132

    C3-6

    Conversions and Casts

    Some conversions are performed automatically

    (See K&P, p. 132)

    But sometimes conversions must be coerced by using

    casts.

    A cast takes the form: ()

    Example:

    double d, sqrt(double);

    int i;

    i = 4;

    d = sqrt( (double) i);

    Note: Due to associativity (float)i + 3 is

    equivalent to ((float)i) + 3

  • 8/8/2019 MAE 4733 Notes1

    39/132

    C3-7

    Examples of Constants

    int: 0 77 5013

    long: 0 77L 5013L

    double: 0.003 1.0 0.5013e-2

    char: 'a' 'b' 'c'

    octal: 00 0115 '\033'

    hexadecimal: 0x0 0x4d '\xffff'

    string: "this is a string constant"

    * Note: 2l and 21 are not the same!

    * Type suffixes are acceptable in either upper or

    lower case. Be careful! In this example 2l can

    be represented more clearly as 2L.

  • 8/8/2019 MAE 4733 Notes1

    40/132

    C3-8

    Hexadecimal and Octal Constants

    Decimal Binary Hexadecimal Octal

    0 00000000 00 000

    1 00000001 01 001

    2 00000010 02 002

    3 00000011 03 003

    ...

    31 00011111 1f 037

    32 00100000 20 040

    ...

    188 10111100 bc 274

    ...

    254 11111110 fe 376255 11111111 ff 377

    Conversion Examples:

    0x123 = 1 x 162 + 2 x 161 + 3 x 160 = 291 (decimal)

    0xabc = 10 x 162 + 11 x 161 + 12 x 160 = 2748 (decimal)

    00164 = 1 x 82 + 6 * 81 + 4 x 80 = 116 (decimal)

  • 8/8/2019 MAE 4733 Notes1

    41/132

    C3-9

  • 8/8/2019 MAE 4733 Notes1

    42/132

    C4-1

    Flow of Control

    Relational, Equality, and Logical Operators

    relational operators: less than: less than or equal: =

    equality operators: equal: ==

    not equal: !=

    logical operators: (unary) negation: !logical and: &&logical or: ||

    Logical values: "true" = non-zero"false" = 0

  • 8/8/2019 MAE 4733 Notes1

    43/132

    C4-2

    The Equality Operator

    Example:

    if (x == y)a = x + 500;elsea = 0;

    What does this do?

    y = 0;if (x = y)a = x + 500;elsea = 0;

  • 8/8/2019 MAE 4733 Notes1

    44/132

    C4-3

    The Compound Statement

    Any group of statements (possibly includingdeclarations) enclosed in braces.

    Example:if (a == b)

    {x = 4;

    }else{

    x = 10;printf("a doesn't equal b");}

    The Empty Statement

    The empty statement is just a ';' and is used when wedon't want to do anything until something happens.

    Example: while(x < y);

  • 8/8/2019 MAE 4733 Notes1

    45/132

    C4-4

    The if and the if-else Statements

    if(expression)statement

    Example: if(grade >= 90)

    printf("Congratulations!\n");printf("Your grade is %d.\n", grade);

    if(expression)

    statement1elsestatement2

    Example: if(c >= 'a' && c

  • 8/8/2019 MAE 4733 Notes1

    46/132

    C4-5

    while and for loops

    while for

    ;while() { for(;;)

    ;

    }

    Examples:

    sum = 0;i = 0; sum = 0;while(i < LIMIT) { for(i = 0; i < LIMIT; ++i)

    sum += a[i]; sum += a[i];++i;

    }

  • 8/8/2019 MAE 4733 Notes1

    47/132

    C4-6

    The Comma Operator

    The comma operator in ,

    * separates the two expressions

    * guarantees that gets evaluatedbefore

    * returns the value of and

    * occurs most often in for loops

    Example:

    for(sum = 0, i = 0; i

  • 8/8/2019 MAE 4733 Notes1

    48/132

    C4-7

    The do Statement

    The do statement is a variant of the while statement.

    do

    while();;

    Example: (K&P, p. 173)

    do {printf("Input a positive integer: ");scanf("%d",&n);if(error = (n

  • 8/8/2019 MAE 4733 Notes1

    49/132

    C4-8

    The break and continue Statements

    Examples: (K&P, p. 180)

    while (1) {

    scanf("%lf", &x);if (x < 0.0)break; /* exit loop if x is negative */

    }/* break jumps to here */

    for (i = 0; i < TOTAL; ++i) {c = getchar();if (c >= '0' && c

  • 8/8/2019 MAE 4733 Notes1

    50/132

    C4-9

    The switch Statement

    Example: (K&P, p. 181)

    switch (c) {case 'a':

    ++a_cnt;

    break;case 'b':case 'B':

    ++b_cnt;break;

    default:

    ++other_cnt;}

    /* expression in parentheses following thekeyword switch must be of integral type */

    /* default is optional but should be used */

    /* without break statement execution fallsthrough to next statement */

    Th C diti l O t

  • 8/8/2019 MAE 4733 Notes1

    51/132

    C4-10

    The Conditional Operator

    ? :

    expr_1 is evaluated first.

    If it is true (nonzero) the value of expr_2 isthe value of the conditional expression as awhole.

    If it is false (zero) the value of expr_3 isthe value of the conditional expression as awhole.

    Examples:

    x = (y < z)? y: z;

    What is the result of the following line of code?

    printf("%c",('A'

  • 8/8/2019 MAE 4733 Notes1

    52/132

    C4-11

    What does this print?

    for (i = 0; i < 10; ++i)printf("\n%d",i);

    What does this print?

    x = 1;while (x < 6)

    printf("\nx = %d",x);x += 1;

    printf("\nx = %d",x);

    What gets printed by the following code fragment ifcolor is equal to 2?

    switch(color) {case 1: printf("red");case 2: printf("yellow");case 3: printf("blue");

    }

    F nctions

  • 8/8/2019 MAE 4733 Notes1

    53/132

    C5-1

    Functions

    Earlier example: (K&P, p. 31)

    int main(void)

    { ..

    .max = maximum(max,x);

    min = minimum(min,x);

    .

    .

    .}

    float maximum(float x, float y)

    {

    if(x > y)

    return x;else

    return y;

    }

    * In function definition the function name must be

  • 8/8/2019 MAE 4733 Notes1

    54/132

    C5-2

    * In function definition, the function name must be

    preceded by a type if it returns a non-int value.

    char firstchar(char *s)

    * The returned value will be converted to this type

    upon exit of the function.

    float f(char a, char b, char c)

    {

    int i;

    . . .

    return (i); /* returned value converted */

    }

    * "return" need not return a value, i.e., return();

    or return;. Function should be declared as void.

    * "return" need not be present.

    * Traditional function syntax should still compile

  • 8/8/2019 MAE 4733 Notes1

    55/132

    C5-3

    * Traditional function syntax should still compile

    with an ANSI C compiler.

    float minimum(x, y)

    float x,y; /* These are formal parameters */

    {

    if(x < y)

    return x;else

    return y;

    }

    Note: This is different than

    float minimum(x, y)

    {

    float x,y; /* These are not formal parameters */

    if(x < y)

    return x;else

    return y;

    }

    Function Prototypes

  • 8/8/2019 MAE 4733 Notes1

    56/132

    C5-4

    Function Prototypes

    Functions must be declared before they are used.

    Function prototypes tell the compiler the number and

    type of arguments that are to be passed and the type of

    value to be returned.

    Example:

    #include

    double sqrt(double);

    Most times these function prototype declarations are

    made in a header file.

    #include

    #include /* includes many more lines */

    /* but it's easier this way */

    Note:void f(char, int) is equivalent to void f(char c, int i)

    Storage Classes

  • 8/8/2019 MAE 4733 Notes1

    57/132

    C5-5

    Storage Classes

    * Function arguments are local variables.

    * Any variables declared in the body of a function

    are also local.

    * By default, local variables have the storageclass automatic.

    * Variables which are defined outside of any

    function have the storage class external.

    * Normally, external variables are available to all

    functions.

    (Exception: static external variables.)

    A Summary of Storage Classes in C

  • 8/8/2019 MAE 4733 Notes1

    58/132

    C5-6

    A Summary of Storage Classes in C

    * automatic

    - local to a block

    - discarded when the block is left

    - Unless otherwise specified, variables declared

    within a function or block are "automatic."

    (Includes formal function arguments.)

    * static

    - retain their values throughout the execution of a

    program.

    - must be declared specifically with the "static"attribute.

    - if declared inside a block or function they are

  • 8/8/2019 MAE 4733 Notes1

    59/132

    C5-7

    y

    accessible only within the block or function in

    which they are declared.

    - When a block is exited then later reentered, they

    can be reused without reinitializing them.

    - When declared outside of any function they areexternal in the sense that they are accessible

    within the source file in which they are declared,

    but nowhere else.

    * external

    - are defined outside any function

    - retain their values

    - are accessible to many functions

    - if declared static they are accessible only within

    the file in which they are declared.

    - other external variables are accessible to

  • 8/8/2019 MAE 4733 Notes1

    60/132

    C5-8

    functions in other files only if declared extern

    within those other files

    * register

    - are automatic variables whose values are stored in

    fast registers

    - usually used for a small number of integer indices

    * typedef

    - not really a storage class

    - lets you define identifiers which can be used

    later as if they were data type keywords

    - Example:

  • 8/8/2019 MAE 4733 Notes1

    61/132

    C5-9

    typedef struct {char name[20];

    short age;

    char employee_number[8];

    long gross_pay;

    char address[30];} PERSON_REC;

    Henceforth, "PERSON_REC" can be treated as if it

    were a data type, as in the declaration

    PERSON_REC emp_rec;

    Scope Rules

  • 8/8/2019 MAE 4733 Notes1

    62/132

    C5-10

    * A formal parameter is accessible only within thefunction in which it is declared.

    * A variable declared within a block is accessible in

    the block in which it is declared and in any blocks

    which are nested within the block.

    * If a block contains a declaration of a variable with

    the same name as that of a variable declared in a

    surrounding block, the variable declared in the outer

    block is not accessible until the inner block is

    left.

    * If a function has an "extern" declaration of a

    variable, there must be a corresponding external

    "defining" declaration somewhere among the libraries

    and files constituting the complete program.

    The defining declaration does not contain the keyword

    "extern".

    Examples:

  • 8/8/2019 MAE 4733 Notes1

    63/132

    C5-11

    (K&P, p. 214)

    {

    int a = 2; /* outer block a */

    printf("%d\n", a); /* 2 is printed */

    {int a = 5;

    printf("%d\n", a); /* 5 is printed */

    }

    printf("%d\n", ++a); /* 3 is printed */

    }

    (K&P, p. 218)

    /* In file file1.c */

    #include

    int a = 1, b = 2, c = 3; /* external variables */

    int f(void);

    int main(void)

  • 8/8/2019 MAE 4733 Notes1

    64/132

    C5-12

    {

    printf("%3d\n", f());printf("%3d%3d%3d\n", a, b, c);

    return 0;

    }

    /* In file file2.c */

    int f(void)

    {

    extern int a; /* Look for it elsewhere */

    int b,c; /* Local variables */

    a = b = c = 4;

    return(a+b+c);

    }

    Scope Rules for Functions

  • 8/8/2019 MAE 4733 Notes1

    65/132

    C5-13

    * All C functions have storage class external.

    This means that, generally speaking, every function

    is accessible from anywhere in a program.

    Exception: functions declared "static."

    * Static functions can only be accessed from within the

    file in which they are defined.

    * All programs need function main().

    Execution always begins with main().

    All other functions are subordinate, and are called

    directly or indirectly from main().

    Example:

  • 8/8/2019 MAE 4733 Notes1

    66/132

    C5-14

    static int g(int x){

    /* do something */

    }

    void f(void){

    /* do something else */

    b = g(a);

    }

    f() will call g() located in the same file

    since g() is declared static.

    Other g()'s could exist in other files and

    would not be confused with this g().

    Example of static Attribute:

  • 8/8/2019 MAE 4733 Notes1

    67/132

    C5-15

    void stfun(void)void main(void)

    {

    int i, x;

    for (i=0; i < 10; ++i)

    x = stfun();}

    void stfun(void)

    { static int x = 0; /* x is static: it will retainits value from call to call.

    x gets initialized only once. */

    int y = 0; /* y is automatic: it will loseits value from call to call.

    y gets re-initialized with every

    call. */

    x += 10;y += 10;

    printf("x=%4d\ty=%4d\n", x, y);

    }

    Example of Scope Rules Across Files:

  • 8/8/2019 MAE 4733 Notes1

    68/132

    C5-16

    myprog.c: other.c:

    int a = 2; void osub(int f)

    static int b = 3; {

    extern int a;void main(void) printf("%d\n",a + f);

    { }

    int c = a + b;

    msub(c);

    }

    void msub(int d)

    {

    int e = 7 * d;

    osub(e);

    }

    int z; /* What gets printed *//* by this code fragment? */

  • 8/8/2019 MAE 4733 Notes1

    69/132

    C5-17

    / by this code fragment? /

    void f(int x){ x = 2;z += x;

    }

    void main(void){ z = 5;

    f(z);printf("z = %d\n",z);

    }

    Arrays, Pointers, and Strings

  • 8/8/2019 MAE 4733 Notes1

    70/132

    C6-1

    Arrays

    * C has only one-dimensional arrays, the size of

    which must be fixed as a constant at the time of

    compilation. Indexing of elements starts at 0.

    * An element of an array may be an object of any

    type including another array. This is how multi-

    dimensional arrays are created.

    * Only two things can be done to an array.

    1. Determine its size.

    2. Obtain a pointer to element 0 of the array.

    All other operations are done with pointers.

    Example: (K&P, p. 246)

  • 8/8/2019 MAE 4733 Notes1

    71/132

    C6-2

    #define N 100int a[N]; /* space for a[0] ... a[99] */

    Initialization

    Examples: (K&P, pp. 246 - 247)

    float f[5] = {0.0, 1.0, 2.0, 3.0, 4.0};

    int a[100] = {0}; /* initializes all elements to 0 */

    The compiler can figure out the size of an array if itis initialized when it is defined.

    The following declarations are equivalent.

    int a[] = {2,3,5,-7}; and int a[4] = {2,3,5,-7};

    char s[] = {"abc"}; and char s[] = {'a','b','c','\0'};

    Multidimensional Arrays (K&P, pp. 277 - 282)

  • 8/8/2019 MAE 4733 Notes1

    72/132

    C6-3

    int a[100] one-dimensional array

    int b[2][7] two-dimensional array

    int c[5][3][2] three-dimensional array

    Example:

    int calendar[12][31]; /* calendar is an array of */

    int *p; /* 12 arrays of 31 integer */

    int i, j; /* elements each. */

    Pointers

  • 8/8/2019 MAE 4733 Notes1

    73/132

    C6-4

    * A pointer points to a location in memory.

    * Pointers are used to access memory locations and

    manipulate addresses.

    * Vital for coding real-time applications which

    have fixed addresses for accessing the outside

    world.

    * When variables are passed as arguments to a

    function, their values are copied to the

    corresponding function parameters. This is termed

    "call by value".

    * To change the values of the variables directly,

  • 8/8/2019 MAE 4733 Notes1

    74/132

    C6-5

    pointers are used to provide a "call by reference"

    mechanism.

    Examples:

    int a, c; /* a and c can hold integers */

    int *b; /* b points to an integer variable */

    a = 3;

    b = &a; /* Assign b the address of a */

    c = *b; /* Assign c the contents of the */

    /* address pointed to by b */

    Note: & is the address operator.

    * is the dereference operator.

    Example: (K&P, p. 252):

  • 8/8/2019 MAE 4733 Notes1

    75/132

    C6-6

    #include

    void swap(int *, int *);

    void main(void)

    {

    int i = 3, j = 5;

    swap(&i, &j);

    printf("%d %d\n",i,j); /* 5 3 is printed */

    return 0;

    }

    void swap(int *p, int *q)

    {

    int tmp;

    tmp = *p;*p = *q;

    *q = tmp;

    }

    Array Names as Pointers

  • 8/8/2019 MAE 4733 Notes1

    76/132

    C6-7

    char str[20]; /* (1) allocates 20 bytes for *//* a char array and (2) makes */

    /* str a pointer to the first */

    /* element of the array. */

    x = str[0]; /* stores the first element in x */

    x = *str; /* stores the first element in x */

    if( *str == 32 ) /* tests if the first element */

    /*of the array is a space. */

    if( *(str + 6) == 'A') /* tests if the 7th element */

    { do something } /* of the array is an 'A'. */

    * Note: str is a pointer to the first element of

    the array str[]

    Example: (K&P, p. 255)

  • 8/8/2019 MAE 4733 Notes1

    77/132

    C6-8

    double a[2], *p, *q;

    p = a; /* points to base of array */

    q = p + 1; /* equivalent to q = &a[1] */

    printf("%d\n", q - p); /* 1 is printed */

    printf("%d\n", (int)q - (int)p); /* 8 is printed */

    On most computers, a double is stored in 8 bytes.

    p points to a double and q points to the next double.

    The difference between p and q in terms of arrayelements is 1.

    The difference between p and q in terms of memory

    locations is 8.

    Pointer arithmetic is not equal to memory arithmetic.

    The compiler keeps track of this for us.

    Strings

  • 8/8/2019 MAE 4733 Notes1

    78/132

    C6-9

    * A string is just an array of characters.

    * A string is terminated with the NULL character '\0'.

    Examples:

    char r[100]; /* space for 100 char including '\0' */

    char s[] = "abc"; is equivalent to

    char s[] = {'a', 'b', 'c', '\0'};

    Example: (K&P, p. 270)

    char *p = "abc";

    printf("%s %s\n",p, p+1); /* abc bc is printed */

    Note: We could have used char s[] = "abc"; and 's,s+1'

    Some String Functions

  • 8/8/2019 MAE 4733 Notes1

    79/132

    C6-10

    (See K&P, Appendix A.14, p. 670 - 675)

    char b[50];

    strcpy(b, "blue"); /* string copy */

    if(strcmp(b, "green") == 0) /* string compare */

    printf("It is green!\n");

    strcat(b, " moon"); /* concatenation */

    printf("b = %s\n",b); /* prints blue moon */

    Example:

    strcopy(char *t, char *s) /* copying a string */{

    while( *t++ = *s++ );

    }

    Example:

  • 8/8/2019 MAE 4733 Notes1

    80/132

    C6-11

    unsigned strlen(const char *s){

    register int n;

    for(n = 0; *s != '\0'; ++s)

    ++n; /* finding the string length */

    return n;

    }

    Arguments to main()

    * main() can have two special arguments called

  • 8/8/2019 MAE 4733 Notes1

    81/132

    C6-12

    main() can have two special arguments called

    argc: argument count and

    argv: array of character strings which contain

    the arguments.

    Example: (K&P, p. 291)

    /* Echoing the command line arguments in file my_echo */

    #include

    int main(int argc, char *argv[]){

    int i;printf("argc = %d\n",argc);

    for(i = 0; i < argc; ++i)printf("argv[%d] = %s\n",i, argv[i]);return 0;

    }

    * If the following command line is given

    my echo a is for apple

  • 8/8/2019 MAE 4733 Notes1

    82/132

    C6-13

    my_echo a is for apple

    the following is printed on the screen

    argc = 5

    argv[0] = my_echo

    argv[1] = a

    argv[2] = is

    argv[3] = for

    argv[4] = apple

    What is wrong with the following pieces of code?

  • 8/8/2019 MAE 4733 Notes1

    83/132

    C6-14

    int i, j, a[10];

    for(i = 1; i

  • 8/8/2019 MAE 4733 Notes1

    84/132

    C7-1

    logical operators:

    (unary) bitwise complement: ~

    bitwise and: &

    bitwise inclusive or: |

    bitwise exclusive or: ^

    shift operators:

    left shift: >

    Bitwise Complement

  • 8/8/2019 MAE 4733 Notes1

    85/132

    C7-2

    The int a = 3243 (decimal) = 110010101011 (binary)

    ~a is the bitwise complement of a

    ~a = 001101010100 (binary)

    Note: a + ~a = 111111111111 (binary), i.e., all 1's

    Two's Complement

    The two's complement of an integer is obtained by

    taking the bitwise complement of its binaryrepresentation and adding 1 to it.

    This is how to do subtraction (a + (-b))

    Note: For a given word length, -1 is represented byall 1's. The carry bit is lost when 1 is added, so

    the result is 0.

    Bitwise Binary Logical Operators

  • 8/8/2019 MAE 4733 Notes1

    86/132

    C7-3

    Values of:

    a b a & b a b a | b

    0 0 0 0 0

    1 0 0 1 1

    0 1 0 1 1

    1 1 1 0 1

    Masks

    i i i i i i

  • 8/8/2019 MAE 4733 Notes1

    87/132

    C7-4

    Use bitwise operators to mask individual bits.

    Example:

    0x8 is a mask for bit 3 (4th bit)

    bit 7 6 5 4 3 2 1 0

    0 1 0 1 1 0 1 1 (a number)

    &

    0 0 0 0 1 0 0 0 (mask)

    0 0 0 0 1 0 0 0 (result)

    Example:

    #d fi MASK 0 8

  • 8/8/2019 MAE 4733 Notes1

    88/132

    C7-5

    #define MASK 0x8if(x & MASK)

    {

    /* do something if bit 3 (4th bit) is a '1'*/

    }

    Example: (K&P, p. 337)

    For some int v, the following expression has the value

    1 or 0 depending on the value of bit 2(3rd bit)

    (v & (1

  • 8/8/2019 MAE 4733 Notes1

    89/132

    C7-6

    #include

    void bit_print(int a)

    {

    int i,

    int n = sizeof(int) * CHAR_BIT; /* in limits.h */

    mask = 1

  • 8/8/2019 MAE 4733 Notes1

    90/132

    C7-7

    in declaring identifiers as elements of the set.

    Example: (K&P, p. 345)

    enum day {sun, mon, tue, wed, thu, fri, sat};

    enum day d1, d2;

    .

    .

    .

    if( d1 == d2) /* do something */

    /* By default, sun = 0, mon = 1, ..., sat = 6 */

    /* These variables could have been explicitly

    initialized using other integers */

    enum day {sun = 0,mon,tue,wed = 5,thu,fri,sat = 9}

    /* Note: mon = 1, tue = 2, thu = 6, fri = 7 */

  • 8/8/2019 MAE 4733 Notes1

    91/132

    C7-8

    Example: (K&P, p. 345)

    enum suit {clubs = 1, diamonds, hearts, spades} a,b,c;

    Note that diamonds = 2, hearts = 3, and spades = 4

    Example: (K&P, p. 348)

    /* Compute the next day with a cast */

    enum day {sun, mon, tue, wed, thu, fri, sat};

    typedef enum day day;

    day find_next_day(day d)

    {day next_day

    return ((day)(((int)d + 1) % 7));

    }

    The Preprocessor

    * The general sequence of events that takes place

  • 8/8/2019 MAE 4733 Notes1

    92/132

    C8-1

    during programming is

    edit ---> compile ---> link ---> execute

    * Preprocessing occurs between edit and compile.

    * The preprocessor does not detect syntax errors.

    e.g., the following substitution will be made

    without complaint.

    #define FORMULA (al+a2]*a3

    * The symbol '#' usually must be in column 1.

    The Use of #include

    * Facilitates including code from other files.

  • 8/8/2019 MAE 4733 Notes1

    93/132

    C8-2

    * Allows common declarations and definitions to be

    kept in separate files.

    * These can then be used in many programs and by many

    programmers.

    * #include files can be nested.

    * They commonly have the extension ".h", as in

    "stdio.h". These are called header files.

    Example:

    What the preprocessor sees:

  • 8/8/2019 MAE 4733 Notes1

    94/132

    C8-3

    myprog.c defs.h

    #include "defs.h" typedef struct {

    char name[30];void main(void) int salary;

    { } EMP_REC;

    EMP_REC employee;

    char buffer[BUFFSIZE+1]; #define mod(x,y) \

    . (x)%(y)

    . #define BUFFSIZE 1000

    .a = mod(a,c);

    .

    ..}

    What the preprocessor sees after the #include:

    mprog.c

  • 8/8/2019 MAE 4733 Notes1

    95/132

    C8-4

    typedef struct {

    char name[30];

    int salary;

    } EMP_REC;

    #define mod(x,y) (x)%(y)

    #define BUFFSIZE 1000

    void main(void)

    {EMP_REC employee;

    char buffer[BUFFSIZE+1];

    . . .a = mod(a,c);

    . . .}

    What the compiler sees (after preprocessing):

    mprog.c

  • 8/8/2019 MAE 4733 Notes1

    96/132

    C8-5

    typedef struct {

    char name[30];

    int salary;

    } EMP_REC;

    void main(void)

    {

    EMP_REC employee;

    char buffer[1000+1];

    .

    .

    .a = (a)%(c);

    .

    ..}

    The Use of #define

    * In effect, #define gives a name to a constant.

  • 8/8/2019 MAE 4733 Notes1

    97/132

    C8-6

    In effect, #define gives a name to a constant.

    * It makes "magic numbers" easier to see.

    * It can be used to change a value utilized many places

    in your code by just changing one #define

    statement.

    Examples:

    #define SECTORSIZE 512

    #define BUFFERSIZE 3*SECTORSIZE

    #define MESSAGE "error no. %d\n"

    #define READWRITE 2

  • 8/8/2019 MAE 4733 Notes1

    98/132

    C8-7

    #define BASE_ADDRESS 0x2e

    #define COMM_REG BASE_ADDRESS + 1

    void main(void)

    {

    char filebuf[BUFFERSIZE + 1];

    ...printf(MESSAGE,n);

    ...open(filename, READWRITE);

    ...

    }

    Macros and Macro Arguments

    * If a left parenthesis immediately follows the name,

  • 8/8/2019 MAE 4733 Notes1

    99/132

    C8-8

    p y ,

    it is assumed to contain a list of "formal

    arguments".

    * If the macro definition includes formal arguments

    the actual arguments are substituted for the

    formal arguments.

    * May look like a way to implement functions, but

    remember that Macros are not functions!

    Examples:

    #define mod(x,y) (x) % (y) /* x and y are "arguments" */

  • 8/8/2019 MAE 4733 Notes1

    100/132

    C8-9

    ...a = 17 + mod(42,max); /* expands to */

    /*a = 17 + (42) % (max); */

    (K&P, p. 368)

    #define SQ(x) ((x) * (x))

    ...SQ(7 + w); /* expands to */

    /* ((7 + w) * (7 + w)); */

    * Why the extra parentheses?

    /* Define using no parentheses. */

    #define mod(x,y) x % y

    ...a = mod(42,max+1);

    /* expands to a = 42 % max + 1;

  • 8/8/2019 MAE 4733 Notes1

    101/132

    C8-10

    * Since'%' has precedence over '+',the result is

    * a = (42 % max) + 1;

    */

    Similarly (K&P, p. 368),

    #define SQ(x) x * x

    SQ(a + b);

    /* expands to a + b * a + b which because of

    * precedence is not (a+b)2

    */

    Conditional Compilation

    #undef

  • 8/8/2019 MAE 4733 Notes1

    102/132

    C8-11

    * Makes the preprocessor forget the definition of

    .

    * Allows one to redefine , or to not have it

    conflict with some other use of .

    * Some compilers let you redefine a macro without first

    using #undef.

    * The conditional compilation commands allow lines

    of source code to be included or not included

    in a compilation.

    #if...#else...#endif

    * #if...#else...#endif tests whether some constant

  • 8/8/2019 MAE 4733 Notes1

    103/132

    C8-12

    integral expression is true (non-zero) or false

    (zero).

    #ifdef and #ifndef

    * #ifdef and #ifndef tests whether or not some constant

    or macro has been defined or not.

    Example:

    #define DEBUG 1 /* could also omit the '1' */

  • 8/8/2019 MAE 4733 Notes1

    104/132

    C8-13

    .

    .

    .#if DEBUG /*must be a "constant expression" */

    printf(" %d iterations.\n", count++);

    if (count > 100) return;

    #else

    if (count++ > 100) return;

    #endif

    Example:

    #define SUN_4 1

  • 8/8/2019 MAE 4733 Notes1

    105/132

    C8-14

    .

    .#ifdef SUN_4

    {SUN_4-dependent code}

    #endif#ifdef VAX

    {VAX-dependent code}

    #endif

    #ifdef IBM_PC

    {IBM_PC-dependent code}#endif

    #ifndef MAXLENGTH

    #define MAXLENGTH 100

    #endif

    #line

    * This preprocessing directive causes the compiler

  • 8/8/2019 MAE 4733 Notes1

    106/132

    C8-15

    * This preprocessing directive causes the compiler

    to renumber the source text so that the next

    line is associated with the specified number.

    Example:

    /*Suppose the following line is number 25 */

    #define BIGMAC lots and lots of stuff that takes \

    up, oh, maybe eight or nine lines \

    Since these lines are treated as \

    one by the compiler,the compiler's\

    error messages will all be off by \

    9 lines which makes it really \

    hard to connect error messages \

  • 8/8/2019 MAE 4733 Notes1

    107/132

    C8-16

    hard to connect error messages \

    with the lines on which they \

    actually occurred.

    #line 35

    b = min(x,y); /* This should be line 35 */

    .

    .

    .

    "I didn't mean THAT!"

    * What is incorrect or dangerous about each of the

  • 8/8/2019 MAE 4733 Notes1

    108/132

    C8-17

    What is incorrect or dangerous about each of the

    following code fragments?

    #define MAX = 5

    #define MAX 5;

    #define GETHEAD #include

    * ANSI C preprocessors are supposed to be smart

    enough to not expand the following macro until

    an 'out of memory core dump' message appears

    on the console. How does your preprocessor

    expand this macro?

  • 8/8/2019 MAE 4733 Notes1

    109/132

    C8-18

    expand this macro?

    #define forever(x) x forever(x)

    * Consider the following code fragment. What is the

    value of b after execution of the following

    statements?

    #define SQUARE(x) (x) * (x)

    a = 2;

    b = SQUARE(a++);

    * It is good to be reminded that macros are not

    functions no matter how tempting it may be.

    What is the effect of the following code?

  • 8/8/2019 MAE 4733 Notes1

    110/132

    C8-19

    What is the effect of the following code?

    #define N 3

    #define max(a,b) ((a)>(b)? (a): (b))

    void main(void)

    { int i, biggest, x[N] = {2, 3, 1};

    biggest = x[0];

    i = 1;

    while(i < N)

    biggest = max(biggest, x[i++]);

    printf("biggest = %d\n", biggest);

    } /* Could it be possible that biggest = 1? */

    Structures and Unions

    Structures

  • 8/8/2019 MAE 4733 Notes1

    111/132

    C9-1

    * Provides a mechanism to aggregate variables of

    different types.

    * Although not required, it is good practice to

    associate a tag name with the structure type.

    * Can be used with typedef and placed in header files

    to facilitate modularity and portability.

    Example: (K&P, pp. 407 - 408)

    Set up a structure to characterize playing cards.

    struct card {

  • 8/8/2019 MAE 4733 Notes1

    112/132

    C9-2

    int pips;

    char suit;

    }

    struct card c1, c2;

    One could have done this at the 'same' time.

    struct card {

    int pips;

    char suit;

    } c1, c2;

    Example: (K&P, p. 410)

    Define a complex number structure using typedef.

    typedef struct {

  • 8/8/2019 MAE 4733 Notes1

    113/132

    C9-3

    float re;

    float im;

    } complex;

    complex a, b, c[100];

    Accessing Members of a Structure

    * Member access operators ( '.' and '->') are used

    to access the individual members of a struct.

    Example: (K&P, p. 411 - 412)

    /* In file class_info.h */

    #define CLASS_SIZE 100

  • 8/8/2019 MAE 4733 Notes1

    114/132

    C9-4

    struct student {

    char *last_name;

    int student_id;

    char grade;

    };

    /* In 'main' program */

    #include "class_info.h"

    int main(void) {

    struct student tmp, class[CLASS_SIZE];

    . . .

    tmp.grade = 'A';

  • 8/8/2019 MAE 4733 Notes1

    115/132

    C9-5

    tmp.last_name = "Casanova";

    tmp.student_id = 910017; . . .

    /* Function to count the number of failing grades */

    int fail(struct student class[])

    { int i, cnt = 0;

    for(i = 0; i < CLASS_SIZE; ++i)

    cnt += class[i].grade == 'F';

    return cnt;}

    * C provides the member access operator '->' to access

    the members of a structure via a pointer.

    Example: (K&P, p. 413 - 414)

  • 8/8/2019 MAE 4733 Notes1

    116/132

    C9-6

    /* In file complex.h */

    struct complex {

    double re; /* real part */

    double im; /* imaginary part */

    };

    typedef struct complex complex;

    /* complex and complex in different name spaces */

    /* better to use typedef directly */

    /* In 'main' source file */

    #include "complex.h"

    void add(complex *a, complex *b, complex *c)

  • 8/8/2019 MAE 4733 Notes1

    117/132

    C9-7

    {

    a -> re = b -> re + c -> re;

    a -> im = b -> im + c -> im;

    }

    /* pointer_to_struct -> member_name

    is equivalent to

    (*pointer_to_struct).member_name */

    Using Structures with Functions

    * In ANSI C, structures can be passed as arguments

    t f ti d b t d f th

  • 8/8/2019 MAE 4733 Notes1

    118/132

    C9-8

    to functions and can be returned from them.

    * When a structure is passed as an argument to a

    function, it is passed by value.

    * Due to speed considerations, it may be

    advantageous to pass pointers.

    * A struct can have as one or more of its members

    another struct.

    Example: (K&P, pp. 416 - 417)

    struct dept {

    char dept_name[25];

  • 8/8/2019 MAE 4733 Notes1

    119/132

    C9-9

    int dept_no;

    }

    typedef struct {

    char name[25];

    int employee_id;

    struct dept department;

    struct home_address *a_ptr;

    double salary;

    ...

    } employee_data;

    /* A function to update employee data */

  • 8/8/2019 MAE 4733 Notes1

    120/132

    C9-10

    employee_data update(employee_data e)

    { ...

    printf("Input the department number: ");

    scanf("%d", &n);

    e.department.dept_no = n;

    ...

    return e;

    }

    * Call by value requires that a copy of the data be

    supplied to the function. This could take some

    time if large structures are being passed so a

  • 8/8/2019 MAE 4733 Notes1

    121/132

    C9-11

    second approach using pointers follows.

    void update(employee_data *p)

    { ...

    printf("Input the department number: ");

    scanf("%d", &n);

    p->department.dept_no = n;

    ...}

    * In main() or some other function one could write

    for the first case

    employee data e;

  • 8/8/2019 MAE 4733 Notes1

    122/132

    C9-12

    employee_data e;

    e = update(e);

    and in the second case

    employee_data e;

    update(&e);

    * Note that in the first case

    e.department.dept_no = (e.department).dept_no

    and in the second case

    p->department.dept_no = (p->department).dept_no

    Unions

    * Same as a structure except members share memory

    storage.

  • 8/8/2019 MAE 4733 Notes1

    123/132

    C9-13

    * Size of union is size of largest member.

    * Since data overlaps, the system will interpret the

    same stored bit values according to which member

    component is selected.

    Example: (K&P, pp. 424 - 425)

    typedef union int_or_float {

    int i;

  • 8/8/2019 MAE 4733 Notes1

    124/132

    C9-14

    float f;

    } number;

    int main(void)

    {

    number n;

    n.i = 4444;

    printf("i: %10d f: %16.10e\n", n.i, n.f);

    n.f = 4444.0;

    printf("i: %10d f: %16.10e\n", n.i, n.f);

    }

    /* The output of this program is system dependent *//* One example follows */

  • 8/8/2019 MAE 4733 Notes1

    125/132

    C9-15

    / p /

    i: 4444 f: 0.6227370375e-41

    i: 1166729216 f: 4.4440000000e+03

    * What is the result of the following program?

    #if(VAX || PC)

    #define HEX0 0x6c6c6548

    #define HEX1 0x77202c6f

    #define HEX2 0x646c726f

    #define HEX3 0x00000a21

    #else

    #define HEX0 0x48656c6c

    #define HEX1 0x6f2c2077

  • 8/8/2019 MAE 4733 Notes1

    126/132

    C9-16

    #define HEX2 0x6f726c64

    #define HEX3 0x210a0000

    #endif

    typedef union {

    char what[16];

    long cipher[4];

    } mystery;

    void main(void)

    {

    mystery x;

  • 8/8/2019 MAE 4733 Notes1

    127/132

    C9-17

    x.cipher[0] = HEX0;

    x.cipher[1] = HEX1;

    x.cipher[2] = HEX2;

    x.cipher[3] = HEX3;

    printf("%s", x.what);

    }

    * Given the following struct definition it appears

    that the string defined as the first member is

    of unknown size. Will the compiler complain?

  • 8/8/2019 MAE 4733 Notes1

    128/132

    C9-18

    If not, resolve this paradox.

    #define CLASS_SIZE 100

    struct student {

    char *last_name;

    int student_id;

    char grade;

    }

    Input / Output

    * read from and write to the standard I/O devices.

    printf("control string", args to be printed);

  • 8/8/2019 MAE 4733 Notes1

    129/132

    C11-1

    scanf("control string", ptrs to args to be read);

    * read from and write to general files or devices.

    fprintf(file_ptr, "control string", arguments);

    fscanf(file_ptr, "control string", ptrs to args);

    * Three standard file pointers , stdin, stdout, and

    stderr, are defined in stdio.h.

    Example: (K&P, p. 505)

    #include

    int main(void){ int a, sum = 0; /* FILE defined in stdio.h */

    ILE if f / S /

  • 8/8/2019 MAE 4733 Notes1

    130/132

    C11-2

    FILE *ifp, *ofp; /* See K&P, pp. 653 - 662 */

    ifp = fopen("input.dat", "r");

    ofp = fopen("output.dat", "w");

    while(fscanf(ifp,"%d", &a) == 1)sum += a;

    fprintf(ofp,"The sum is %d.\n", sum);

    fclose(ifp);fclose(ofp);

    return 0}

    * fprintf(stdout,...); and printf(...); are equivalent.

    * fscanf(stdin,...); and scanf(...); are equivalent.

    * td i t t th l d fi d

  • 8/8/2019 MAE 4733 Notes1

    131/132

    C11-3

    * stderr points to the screen unless redefined.

    Read/Write Mode Meaning

    "r" open for reading

    "w" open for writing

    "a" open for appending

    "r+" reading and writing

    "w+" writing and reading

    Some Conversion Characters

    c char

    d,i decimal int

  • 8/8/2019 MAE 4733 Notes1

    132/132

    C11-4

    u unsigned decimal int

    o unsigned octal int

    x,X unsigned hex int

    e,E scientific notation (7.123e+00 or 7.123E+00)

    f fixed floating point (7.123)

    g,G e,E or f format, whichever is shorter

    s string