• No results found

Variables and Expressions

In document Embedded Systems Shape the World (Page 65-68)

Checkpoint 4.11. What does negative logic mean?

5.3 Variables and Expressions

Program 5.2. Software to calculate the area of a square room.

There are two types of comments. The first type explains how to use the software. These comments are usually placed at the top of the file, within the header file, or at the start of a function. The reader of these comments will be writing software that uses or calls these routines. The second type of comments assists a future programmer (ourselves included) in changing, debugging or extending these routines.

We usually place these comments within the body of the functions. The comments on the right of each line are examples of the second type.

Preprocessor directives begin with # in the first column. As the name implies preprocessor commands are processed first. I.e., the compiler passes through the program handling the preprocessor directives.

Although there are many possibilities (assembly language, conditional compilation, interrupt service routines), I thought I’d mention the two most important ones early in the class. We create a macro using

#define to define constants.

#define SIZE 10

Basically, wherever SIZE is found as a token, it is replaced with the 10. A second important directive is the #include, which allows you to include another entire file at that position within the program. The

#include directive will include the file named tm4c123ge6pm.h at this point in the program. This file will define all the I/O port names for the TM4C123.

#include "tm4c123ge6pm.h"

5.3 Variables and Expressions

Variables are used to hold information. In C, we define a variable by specifying the name of the variable and the type. Table 5.3 lists the possible data types.

Data type Precision Range

unsigned char 8-bit unsigned 0 to +255 signed char 8-bit signed -128 to +127 unsigned int compiler-dependent

int compiler-dependent

unsigned short 16-bit unsigned 0 to +65535 short 16-bit signed -32768 to +32767 unsigned long unsigned 32-bit 0 to 4294967295L

long signed 32-bit -2147483648L to 2147483647L float 32-bit float ±10-38 to ±10+38

double 64-bit float ±10-308 to ±10+308

Table 5.2. Data types in C.

On the Keil compiler, there is an option to specify whether char all by itself without a signed or unsigned before it is considered signed or unsigned. Keil considers int as 32 bits. In this class we will avoid int and use long for 32-bit variables so there is no confusion. We will assume char is signed, but it is good practice to see exactly how char and int are treated by your compiler.

Variables declared outside of a function, like M in Program 5.1, are properly called external variables because they are defined outside of any function. While this is the standard term for these

variables, it is confusing because there is another class of external variable, one that exists in a separately compiled source file. In this document we will refer to variables in the present source file as globals, and we will refer to variables defined in another file as externals. There are two reasons to employ global variables. The first reason is data permanence. The other reason is information sharing.

Normally we pass information from one module to another explicitly using input and output parameters, but there are applications like interrupt programming where this method is unavailable. For these situations, one module can store data into a global while another module can view it.

Local variables are very important in C programming. They contain temporary information that is accessible only within a narrow scope. We can define local variables at the start of a compound statement. We call these local variables since they are known only to the block in which they appear, and to subordinate blocks. The variables side and area in Program 5.3 are local. In C, local variable must be declared immediately after a brace { that begins a compound statement. Unlike globals, which are said to be static, locals are created dynamically when their block is entered, and they cease to exist when control leaves the block. Furthermore, local names supersede the names of globals and other locals declared at higher levels of nesting. Therefore, locals may be used freely without regard to the names of other variables. Although two global variables cannot use the same name, a local variable of one block can use the same name as a local variable in another block. Programming errors and confusion can be avoided by understanding these conventions. Local variables are implemented in registers or allocated on the stack.

Program 5.3 illustrates the assignment operator. Notice that in the line side=3; the side is on the left hand side of the = . The left side of the assignment specifies the address into which the data transfer will occur. On the other hand, if we were to wrote area=side; the side is on the right hand side of the = . The right side of an assignment statement will evaluate into a value, which specifies the data to be transferred. Notice that the line area=side; creates two copies of the data. The original value remains in side, while area also contains this value. As mentioned above, variables have a type (Table 5.3), and the expression on the right of an assignment statement must evaluate to a value of that same type. If side has the value 3, the expression side*side evaluates to a 9, and the 9 is stored into the variable area. The printf is used to output the results to the uart port.

int main(void) {

unsigned long side; // room wall meters unsigned long area; // size squared meters

UART_Init(); // call subroutine to initialize the uart side = 3;

area = side*side;

printf("\nArea of the room with side of %ld m is %ld sqr m\n",side,area);

}

Program 5.3. Simple program illustrating variables and assignment statements.

Program 5.4 illustrates the arithmetic operations of addition, subtraction, multiplication and division. In the operation x+4*y, multiplication has precedence over addition. Table 5.4 lists the operators available in the C language.

y += 2; // same as y=y+2;

}

Program 5.4. Simple program illustrating C arithmetic operators.

Operation Meaning Operation Meaning

Table 5.4. Special characters can be operators; operators can be made from 1, 2, or 3 characters.

As with all programming languages the order of the tokens is important. There are two issues to consider when evaluating complex statements. The precedence of the operator determines which operations are performed first. In expression z=x+4*y, the 4*y is performed first because * has higher precedence than + and =. The addition is performed second because + has higher precedence than =. The assignment

= is performed last. Sometimes we use parentheses to clarify the meaning of the expression, even when they are not needed. Therefore, the line z=x+4*y; could have been written as z=(x+4*y);

z=(x+4*y); or z=(x+(4*y));

The second issue is the associativity. Associativity determines the left to right or right to left order of evaluation when multiple operations of equal precedence are combined. For example + and - have the same precedence, so how do we evaluate the following?

z = y-2+x;

We know that + and - associate the left to right, this function is the same as z=(y-2)+x;. Meaning the subtraction is performed first because it is more to the left than the addition. Most operations associate left to right, but the Table 5.5 illustrates that some operators associate right to left.

Observation: When confused about precedence (and aren't we all) add parentheses to clarify the expression.

< <= > >= Left to right

Table 5.5. Precedence and associativity determine the order of operation.

In document Embedded Systems Shape the World (Page 65-68)