11.26 Programming style, command line arguments to main, advances console output
intro-to-computer-science-gtiit-07-2024.pdf
Naming
- Good code should be mostly self-documenting.
- Variable names should make it clear what you are doing.
-
At the moment, we are still writing short and simple programs, so typically short generic names are sufficient:
-
Indexes:
i
,j
,k
, … - Accumulators/User Input:
a
,b
,c
, … - For longer and more complex programs, variable names must be more meaningful of the entities that the variables represent, avoiding very long names.
Naming Examples
Purpose of Variable | Good Names, Good Descriptors | Bad Names, Poor Descriptors |
---|---|---|
Running total of checks written to date | runningTotal ,checkTotal |
written , ct , checks , CHKTTL , x , x1 , x2 |
Velocity of a bullet train | velocity , trainVelocity , velocityInMph |
velt , v , tv , x , x1 , x2 , train |
Current date | currentDate , todaysDate |
cd , current , c , x , x1 , x2 , date |
Lines per page | linesPerPage |
lpp , lines , l , x , x1 , x2 |
Optimal Name Length
-
The optimal length seems to be somewhere between:
-
x
-
maximumNumberOfPointsInModernOlympics
- Names that are too short do not convey enough meaning. In small programs, these are sometimes acceptable.
- Names that are too long can obscure the visual structure of the program.
Multiple-Word Variable Names
- Multiple-word variables should be formatted consistently.
- For example,
"hashtable_array_size"
or"hashtableArraySize"
are both okay, but"hashtable_arraySize"
is not. - If you use
"hashtable_array_size"
in one place in a program, using"hashtableArray"
somewhere else in the program would not be okay. - Some developers prefer the camelCase naming style (
"hashtableArray"
, etc.).
Comments
- Comments should be present in your programs, but not excessively.
-
Comments can be useful in:
-
File header: A good place to put your name and email address, and a comment describing the purpose of the file if it fits into a larger project.
- Large blocks of code: If a block of code is particularly long, a comment at the top can help the reader know what to expect as they’re reading it, and let them skip it if it’s not relevant.
- Tricky bits of code: If there’s no way to make some code self-evident, then it is acceptable to describe what it does with a comment.
Indentation
- Proper indentation can greatly increase the readability of code.
- Every time you open a block of code (
if
statement,for
orwhile
loop, a function, etc.), you should indent one additional level. - You are free to use your own indent style, but you must be consistent: if you use 2 spaces as an indent in some places, you should not use 4 spaces or a tab elsewhere.
- Not sure what style to use? Use Kernighan & Ritchie style:
$ indent -kr myfile.c
Line Length
-
We require program lines to be no longer than 80 characters, so that code can be viewed without side scrolling.
-
(This is due to historical reasons, but it’s still mostly the case in terminals.)
- It also helps to maintain a relatively simple program structure.
- If you indent with tabs, assume a tab size of 2 characters when calculating line lengths.
- To see the maximum line length of
file.c
, run:
$ wc -L file.c
No Magic Numbers
- Magic numbers are numbers in your code that have more meaning than simply their own values.
-
For example:
for(i=0;i<20;i++) x += i;
and thenx / 20
. -
20
is a magic number. - Using named constants also makes your program easier to modify.
- Use
#define
to clarify the meaning of magic numbers. In the above example:
#define TOTAL 20
then for(i=0; i<TOTAL; i++) x += i;
and then x / TOTAL;
No Dead Code
- Dead code is code that is not run when your program runs.
- Sometimes this happens because of an always true/false condition, or because of an early break or return.
- Your submissions should have no dead code in it.
Example:
int foo(void) {
int a = 24;
int b = 25; // assignment to dead variable
int c;
c = a * 4;
return c;
b = 24; // unreachable code
return 0;
}
No Surprises
- Code must be as straightforward as possible.
-
Use good programming practices:
-
Structured programming / Good forms of iteration.
- Avoid unnecessary variables.
-
Avoid unnecessary features:
-
If arrays are not needed, do not use them.
- You impose more work on those who read your code when you add unnecessary things to your programs.
Fixing Bugs
When doing a programming homework or project, you will often realize that your program has bugs that need to be fixed.
Set a time limit:
-
0 minutes: Run with:
gcc -Wall
-
1–10 minutes: Active debugging:
-
Say out loud what the problem is.
- Describe what you expect your code to do.
- Read it step by step from the beginning.
- Speak to someone near you.
- >10 minutes: Take a break or ask for help.
Summary
- Programs can become very complex and difficult to reason about.
-
It is important that we favor readability in programs to favor extensibility/reuse/maintenance:
-
Programs need to be read to be extended, reused, and maintained.
- A lot more time is spent in extension/reuse/maintenance than the time spent for the initial program construction.
-
Programs will most likely have defects:
-
Be systematic about finding and fixing bugs.
- Use tool support for debugging.
main()
's First Parameter: argc
- We have been using
main()
as a function with no parameters. - Think of
main()
's parameters as variables that tell how the program was executed from the command line. -
main()
can have two specific parameters: -
We will see the first one now:
argc
. -
argc
stands for argument count. - It’s the number of words in the command line used when the program was executed.
Example
- Write a program that prints the value of the integer parameter
argc
usingprintf
.
#include <stdio.h>
int main(int argc) {
// Print the number of command-line arguments
printf("Number of arguments: %d\n", argc);
return 0;
}
Try:
$ gcc argc.c -o argc
$ ./argc
$ ./argc x
$ ./argc x x
$ ./argc x x x x
Escape Sequences and the Escape Character
-
An escape sequence is a sequence of characters that has a meaning other than the literal characters of the sequence.
-
Typically used to represent non-printable characters and send other styling commands to the terminal.
-
\e
: Represents the escape character (ESC in ASCII table, value$1B
). - Escape sequences are supported by many programming language compilers and interpreters (supported by
gcc
andtcc
, although not part of the C standard).
ANSI Escape Codes
- ANSI Escape Codes are enabled when printing the Escape Character.
- Almost all terminal emulators support them.
-
Three main categories of codes:
-
Text attributes: bold, underline, blink.
- Foreground (text) color.
- Background color.
List of Attributes and Colors
Text Attributes
Escape Sequence | Text Attributes |
---|---|
\x1b[0m |
All attributes off (color at startup) |
\x1b[1m |
Bold on (enable foreground intensity) |
\x1b[4m |
Underline on |
\x1b[5m |
Blink on (enable background intensity) |
\x1b[21m |
Bold off (disable foreground intensity) |
\x1b[24m |
Underline off |
\x1b[25m |
Blink off (disable background intensity) |
Foreground Colors
Escape Sequence | Foreground Colors |
---|---|
\x1b[30m |
Black |
\x1b[31m |
Red |
\x1b[32m |
Green |
\x1b[33m |
Yellow |
\x1b[34m |
Blue |
\x1b[35m |
Magenta |
\x1b[36m |
Cyan |
\x1b[37m |
White |
\x1b[39m |
Default (foreground color at startup) |
\x1b[90m |
Light Gray |
\x1b[91m |
Light Red |
\x1b[92m |
Light Green |
\x1b[93m |
Light Yellow |
\x1b[94m |
Light Blue |
\x1b[95m |
Light Magenta |
\x1b[96m |
Light Cyan |
\x1b[97m |
Light White |
Background Colors
Escape Sequence | Background Colors |
---|---|
\x1b[40m |
Black |
\x1b[41m |
Red |
\x1b[42m |
Green |
\x1b[43m |
Yellow |
\x1b[44m |
Blue |
\x1b[45m |
Magenta |
\x1b[46m |
Cyan |
\x1b[47m |
White |
\x1b[49m |
Default (background color at startup) |
\x1b[100m |
Light Gray |
\x1b[101m |
Light Red |
\x1b[102m |
Light Green |
\x1b[103m |
Light Yellow |
\x1b[104m |
Light Blue |
\x1b[105m |
Light Magenta |
\x1b[106m |
Light Cyan |
\x1b[107m |
Light White |
Sources
Example in a C Program
#include <stdio.h>
#define RESET "\e[0m"
#define GREEN "\e[102m"
#define BLUE "\e[104m"
#define MAGENTA "\e[105m"
int main() {
printf("%sHello %sWorld!%s\n", GREEN, MAGENTA, RESET);
return 0;
}