Overview of C part 1 (language, flow, data types)

advertisement
clark
cs1713
syllabus
lecture notes
programming assignments
Another complete program example.
In this example, instead of reading the data from a file, we only get the
average of grades entered directly on the command line.
int main()
Within your program, there should be exactly one int main(). This is the
function that begins execution. It is passed an array of pointers to strings
and a count of the number of items in the array. It returns an integer. By
convention, 0 is returned for normal return. The contents of argv includes
the command name and the command line arguments to this program.
Example: average program
Suppose the program average is passed a list of integers and
returns the average. In unix, we would invoke it by keying
$ ./average 10 20 40 30
25.00000
If the average program is passed this
$ ./average 90 100
argc will be 3:
argv[0] -> "average"
argv[1] -> "90"
argv[2] -> "100"
homework
set up
#include <stdio.h>
int main(int argc, char *argv[])
{
double dSum = 0.0;
int i;
int iScanfCount;
// count of the successful
// conversions in sscanf
int iNum;
// number from the command line
/* check for no arguments */
if (argc < 2)
{
fprintf(stderr, "Error: must pass values to average");
return 0;
}
for (i = 1; i < argc; i++)
{
// convert command argument to int
iScanfCount = sscanf(argv[i], "%ld", &iNum);
// sscanf returns the number of successful formats
if (iScanfCount < 1)
{
fprintf(stderr, "Invalid command argument: %s"
, argv[i]);
return -1;
}
dSum += iNum;
}
printf("%lf", dSum / (argc - 1));
return 0;
}
variables
dataType variableName = initialValue;
int iStudentCount;
The intialization is optional.
int iStudentCount = 0;
Some of the data types:
int iOrderQuantity = 0;
int - integer (could be 2 or 4 bytes depending on implementation)
double dAverage = 0.0;
long - on most 32-bit machines, 4 bytes; on most 64-bit machines, 8
bytes
char cLetterGrade = 'F';
float - 4 byte floating point
int bEOFEncountered = 0;
// 0 is false, non-zero
// is true.
double - 8 byte floating point
char - single character; one byte
To declare an array:
dataType variableName[numberOfElments];
dataType variableName[] = {initialValueList};
Note that subscripts in C begin with 0. (Some languages have subscripts that
begin with 1 such as COBOL and FORTRAN. PL/I by default begins with 1,
but can be changed to any integer.)
double dExamWeightingM[3] = {200.0, 200.0, 300.};
To declare a string of characters (note strings end with a zero byte
terminator):
char variableName[sizePlus1];
char variableName[] = initialValue;
A zero byte is the constant '\0'. A literal character string surrounded in
double quotes is automatically terminated with a zero byte.
char szFirstName[21];
Note that arrays of characters do not have to be zero byte terminated, but if
they aren't, several C functions do not work properly. We try to be clear in
coding for whether the string is zero-terminated or not. Our convention:
szName- string terminated by zero byte
sbName - string not terminated by zero byte. It might contain binary
data.
#define NUMBER_OF_EXAMS 3
double dExamWeightingM[NUMBER_OF_EXAMS]
= {200.0, 200.0, 300.};
double dExamWeightingM[] = {200.0, 200.0, 300.};
// max of 20 characters
// plus zero byte
char szFileName[] = "myInput.txt";
char szABC[] = {'A', 'B', 'C', '\0'};
char szABC[] = "ABC";
// automatically zero
// byte terminated
A
B
C
\0
char sbDelims[] = {',', ' ', '\t', '\n'};
int iDelimCount = sizeof(sbDelims);
printf("number of delims = %d\n", iDelimCount);
if statement
The if statement is the most important statement for flow control (as it is in
most languages). Syntax options:
if (conditionalExpression)
truePart;
if (conditionalExpression)
truePart;
else
falsePart;
Comparison operators:
== equal to
!= not equal to
> greater than
< less than
>= greater than or equal to
<= less than or equal to
Logical operators:
&& and
|| or
! not
Warning! Warning! Warning !
== is the equivalence test operator. = is an assignment
operator and must not be used for an equivalence test.
&& is the logical and.
|| is the logical or.
A single & is a bitwise and.
A single | is a bitwise or.
Warning! Warning! Warning!
comparing strings
The equivalence operator (==) cannot be used to
compare strings. The compiler would think it is
comparing addresses.
while statement
The while statement continues to loop while the condition is true (not zero).
if (cLetterGrade == 'W')
{
printf("last day to drop is %s\n", szDropDate);
dCourseGradePoints = 0.0;
dCourseCredits = 0.0;
}
if (dExamScore == 0)
iScoreCount += 1;
if (strcmp(szCommand,"DEPOSIT") == 0)
dBalance += dAmount;
else if (strcmp(szCommand, "WITHDRAWAL") == 0)
{
if (dBalance < dAmount)
{
printf("overdrawn\n");
return(ERROR_OVERDRAWN);
}
else
dBalance -= dAmount;
}
Example of a common mistake:
if (iCount = 3)
That conditional is always true since an assignment
returns its value (3) and 3 is not zero. Since some
other programming languages (e.g., PL/I, SQL) use = for
equivalence tests, this is a common mistake for people
using multiple languages.
if (szCommand == "DEPOSIT")
would check to see if the address of szCommand is
the same as the address for the literal "DEPOSIT".
Use strcmp() or strncmp() for string comparisons.
// read the student data until EOF (fgets returns null pointer)
while (fgets(szInputBuffer, 100, pfileStudentData)!= NULL)
{
Syntax:
while (conditionalExpr)
whileBody;
for statement
The for statement is the iterative loop in C. Unlike Java, you cannot declare a
variable in the ().
for (initializationStmts; conditionalExpr; incrementStmts)
forBody;
When the for statement is encountered, the initalizationStmts are executed.
The for loop continues while the conditionalExpr is non-zero. At the bottom
of each iteration, the incrementStmts are executed.
assigning values
The = operator is used for assigning values. Strings cannot be assigned using
the = operator in C.
variableReference = valueExpr;
Numeric operators:
+
plus
minus
*
multiplication
/
division
++
increment by 1 unit
-decrement by 1 unit
%
modulous (returns remainder)
printf(%s\n", szInputBuffer);
}
// Print the names of students earning an A
for (i = 0; i < iStudentCount; i++)
{
if (studentM[i].dGradeAvrage >= 90)
printf("%s\n", studentM[i].szName);
}
double dAverage;
dAverage = dSum / iCount;
int iVal1 = 10;
int iVal2 = 4;
double dVal;
dCircumference = 2.0 * PI * dRadius;
if (iCount % 5 == 0) // look for a count that is a
// multiple of 5
dVal = iVal1 / iVal2;
Also, there are shortcuts for summing or subtracting values:
variableReference += valueExpr;
variableReference -= valueExpr;
dBalance += dAmount;
dBalance -= dAmount;
//
//
//
//
This is an integer divide
which is 10 / 4 with a
truncated result (2).
dVal is then 2.0
// deposit
// withdrawal
string assignments
Strings are assigned values using
strcpy(target, source);
assigns a null terminated string to the target
strncpy(target, source, length);
assigns length characters from source to target. If the actual
length of source is > length, the result in target won't be null
terminated. If a null byte is encountered before length, no
other characters are copied from source.
char szWinnerFullName[15] = "Anita Break";
char szContestantFullName[15] = "Bob Wire";
strcpy(szWinnerFullName, szContestantFullName);
Value of szWinnerFullName is
B
o
b
W
i
r
e
\0 a
memcpy(target, source, length);
assigns exactly length characters from source to target.
Warning! Warning! Warning!
string assignments can overwrite memory
One of the most common and frustrating bugs in C is overwriting memory.
char szName[10];
char szSpouse[] = "Anita Break";
strcpy(szName, szSpouse);
k
\0 ?
?
?
sizeof and strlen
sizeof ( thing ) is a compile-time function which returns the compile-time
(not runtime) size of the thing.
strlen ( variable ) returns the length of a null-terminated string.
int iCount = 0;
double dPrice = 10.5;
char szNickName[21] = "champ";
struct Account
{
char szAccountNr[15];
double dBalance;
} account = { "123456789", 100.20 };
printf("%-20s %-10s %-10s\n", "Thing", "sizeof", "strlen");
printf("%-20s %-10d %-10s\n", "iCount", sizeof(iCount), "n/a");
printf("%-20s %-10d %-10s\n", "dPrice", sizeof(dPrice), "n/a");
printf("%-20s %-10d %-10d\n", "szNickName", sizeof(szNickName)
, strlen(szNickName));
printf("%-20s %-10d %-10d\n", "szAccountNr"
, sizeof(account.szAccountNr), strlen(account.szAccountNr));
printf("%-20s %-10d %-10s\n", "dBalance"
, sizeof(account.dBalance), "n/a");
printf("%-20s %-10d %-10s\n", "account", sizeof(account)
, "n/a");
Output:
Thing
iCount
dPrice
szNickName
szAccountNr
dBalance
account
Exercise:
Given a name, store the reverse of the name in another array.
char szName[21] = "Perry Scope";
char szReversedName[21];
sizeof
4
8
21
15
8
24
strlen
n/a
n/a
5
9
n/a
n/a
switch statement
The switch statement is used when there are options of what should be done
that are dependent on the value of a variable.
switch (variableReference)
{
case value:
…
// possibly many case value:
statements;
break;
case value:
…
// possibly many case value:
statements;
break;
default:
statements;
}
Notes:
 There may be multiple case value clauses followed by statements.
 A break statement is necessary to specify branching to immediately
after the switch statement.
 default statements are optional. If present, the default will execute
if none of the case values match the value of the variableReference.
switch (cLetterGrade)
{
case 'A':
case 'B':
printf("Better than Average\n");
printf("You are exempt from the exam\n");
break;
case 'C':
printf("About Average\n");
break;
case 'D':
case 'F':
prinf("Below Average\n");
}
break statement in for or while
The break statement can also be used to exit a for or while statement.
Unfortunately, if you have multiple nested looping statements, you can't
specify which one to break out of. It always assumes the immediatley
surrounding switch, while or for.
// keep looping until a player wins
while (TRUE)
{
iResult = takeTurnForPlayer(player1);
if (iResult == PLAYER1_WINNER)
break;
iResult = takeTurnForPlayer(player2);
if (iResult == PLAYER2_WINNER)
break;
// another example
switch (cLetterGrade)
{
case 'A':
case 'B':
case 'C':
case 'D':
printf("You passed\n");
break;
case 'F':
printf("You failed\n");
break;
default:
fprintf(stderr, "unknown grade %c\n"
,cLetterGrade);
}
continue statement in for or while
The continue statement allows you to skip the rest of the code in a loop and
continue with the increment/test. It always assumes the immediatley
surrounding while or for.
}
// keep looping until there is only one player left
while (iNumActivePlayers > 1)
{
// get the next player
iCurrentPlayer++;
if (iCurrentPlayer > iNumPlayers)
iCurrentPlayer = 0;
// if player cannot move, skip him
if (cannotMove(iCurrentPlayer, game) == TRUE)
continue; // skip this player
startTimer(iCurrentPlayer, game);
iResult = takeTurn(iCurrentPlayer, game);
if (iResult == WINNER_DETERMINED)
break;
prepareForNextPlayer(iCurrentPlayer, game);
}
Download