📄 cnews018.doc
字号:
cease being an exciting feature and become a distraction. So, I
wanted to give users the ability to toggle the exploding windows
on and off.
I created an integer variable named "explode_active". When
set to 0, exploding windows are inactive. When set to 1, they
are activated. I then added code that was executed whenever
[F10] was pressed.
My first effort was as follows:
if (explode_active == 0)
explode_active = 1;
else
explode_active = 0;
This works. It is simple and obvious. But, I felt is was
more complicated than this simple function need be. I realized
that I could change the "if" statement to read:
"if(!explode_active)" and produce the same result. But there
had to be a better way. I searched my library of C books (which
number in the dozens) and found nothing on toggles. I left the
code as it was and went on to other things.
A few days later, a thought struck me. If I "XOR" 0 and 1,
Issue C News 14
I get 1. And, if I "XOR" 1 and 1, I get 0. That was just the
operation I wanted for the toggle. I rewrote the routine to be:
explode_active = explode_active ^ 1;
Elegant, simple and not that obvious. And not covered in the
texts. So, the answer to how best deal with toggles is as
follows:
1. Create an integer variable - toggle
2. Assume 0 is off, 1 is on
3. toggle = toggle ^ 1
This is something that almost everyone will use and which slips
through the cracks between the beginner and intermediate books.
For another example, read on!
Jim Singleton recently wrote an article on passing and
accessing command line parameters. I'd like to expand on that
article and talk about command line parsing, an important topic
that is neither as simple nor as obvious as toggles and is
rarely found in the texts.
Sooner or later you will want to pass parameters from the
command line to your program. At first, it may be a simple file
name. Later, a source and destination directory. But,
eventually, you will want to use command line parameters as
configuration switches.
This was the case with VTL. Look at the VTL command
syntax:
VTL - Video Tape Library
VTL was written by Paul E. Castle II
Syntax: VTL [-switches]
-b = BIOS screen writing
-c = CGA snow elimination
-h = Display VTL Syntax
-m = Monochrome attributes forced
-x = Exploding windows active
As you can see, VTL can be configured at startup. The command
to start VTL with exploding windows active, monochrome output,
and BIOS I/O would be:
VTL -x -m -b
Jim, in his article, told you how to process this command
Issue C News 15
line. But, what happens when VTL is started in this manner:
VTL -xmb
In the first case, argc indicates 4 parameters and argv
contains pointers to the path to VTL and the strings -x, -m, and
-b. In the second, argc shows 2 parameters and argv contains
pointers to the path to VTL and the string -xmb. To use the
second form, your program must be capable of parsing, or
separating out, the switches contained in the string -xmb.
Look at the code that follows:
parse_cmd_line(int argc,char *argv[])
{
register int i,j;
char *p;
for(i = 1;i < argc;i++) {
p = argv[i];
if (*p == '-' || *p == '/') {
for(j = 1;*(p+j);j++) {
switch(tolower(*(p+j))) {
case 'b':
setvparam(VP_BIOS);
break;
case 'c':
setvparam(VP_CGA);
break;
case 'm':
setvparam(VP_MONO);
break;
case 'x':
explode_active = YES;
break;
default:
error_exit(2); }
}
}
else
error_exit(2); }
}
Notice that the function "parse_cmd_line" is invoked with
the calling function passing argc and argv. This is the same
syntax as described in Jim's article. Next, look at the "for"
statement: "i" is used as an index into argv, "argv[0]" is the
path to the executing program. In this case, we are not
interested in argv[0] so "i" is set to 1. This will be a
pointer to the first parameter (if any) on the command line.
"i<argc" controls the duration of the loop. We will process the
Issue C News 16
command line as long as "i" is less than argc (remember, argc
will contain the number of command line parameters while the
array argv starts at 0. If argc is 3, argv will have entries 0,
1, and 2). And finally, "i" will be incremented with each
iteration.
The next line sets "p" to point to the string pointed to by
argv[i]. This means that, with each iteration of the "for"
loop, "p" will point to each successive command line parameter.
The "if" statement determines if the first character of the
string, pointed to by "p", is a switch character. VTL allows
either the "-" or the "/" to be used as the switch character.
Now, skip down to the end of the "if" statement. The
"else" statement is executed if a valid command line switch
character if not found. In the case of VTL, "error_exit" is a
function to handle error conditions. Based on the value passed,
"error_exit" prints out an error message and terminates
processing. A value of 2, as in this case, will print out the
VTL syntax.
Back to the top. The next statement establishes a second
loop. The loop will be performed until the condition "*(p+j)"
is false. This is the real key to parsing the command line.
Let's analyze this a little. "p" is set to point to the
beginning of a string. If our command line was "VTL -xm -b" and
"i" is equal to 1, "p" is pointing to the "-" in "-xm". The
second loop (or internal loop) begins with "j" equal to 1. This
means that "*(p+j)" is equal to "x". The reason for this is
that "p" is a pointer to type character. The (p+j) is resolved
by incrementing the address, held by "p", by one character
length, or one byte. The "*" operator says to assume the value
of the address pointed to by "(p+j)". This value is "x".
Therefore, the condition "*(p+j)" is true and the switch
statement is processed. In this case, the value "x" triggers
the "case 'x'" and "explode_active" is set to "YES" (which is
defined as a value of 1). Notice that the switch statement
changes the value pointed to by "(p+j)" to a lower case letter.
This allows the user to enter parameters in either upper case or
lower case.
Once the switch statement has completed, the for loop
cycles again. This time "j" is incremented to 2. In the
example above, "*(p+j)" will now resolve to "m". The loop
cycles again, "j" is incremented to 3, and this time "*(p+j)"
resolves to the NUL char or '\0'. This is because all strings,
in C, are terminated by a '\0' character. The '\0' character
has the ASCII value 0, which equates to false. The internal
loop completes and we return to the first loop and increment
"i". On this next pass, "p" is pointing to the string "-b".
The "b" switch will be processed, as above, and we return to the
Issue C News 17
first loop. This time "i" is set to 3, which is equal to argc,
and the function returns to the calling routine.
One final point. Notice that the default "case" in the
switch statement is to execute "error_exit" with a value of 2.
Whenever an invalid parameter is encountered, the switch will
use the default and, in the case of VTL, display the VTL syntax
and terminate processing.
Command line parsing is a powerful and flexible tool in C
programming. It is also one that is seldom found in the texts.
I hope this helps to fill the gap.
Issue C News 18
=================================================================
WHERE'S THAT NUMBER?: A PROJECT IN PROGRAMMING DESIGN
=================================================================
by Jim Singleton
Back a number of issues ago, Barry and I started what was
to be a series of articles on programming design. (See
"Programming Design: OpusGraf a Project, Part I", issue 13, page
12.) We never finished that series, as noted in issue 14,
because Dan whipped out OpusGraf using AWK, as part of his AWK
introduction. Well, here we go again. (This time, I know Dan
is busy, so he will not jump in and finish this series
prematurely.)
This is going to be a series of articles dealing with
software development. Here at the "C News", we have long
thought that a series on programming design would be helpful to
our readers. While not everyone programs in the same style or
manner, most experienced programmers follow roughly the same
development process. This programming project will follow a
project from the idea stage all the way through the design,
coding, and modification of the program. While we will follow
the "correct" programming guidelines, remember that not everyone
writes their programs in the same way and what may be the right
way for one person is not always the right way for you.
For this series of articles, we will be dealing with a
program called PHONENUM, a short program which displays a phone
number for a name entered on the command line. This first
article, will deal with the first six steps of software design:
1. Defining the Problem
2. Defining the Solution
3. Mapping the Solution
4. Coding the Program
5. Debugging the Program
6. Documenting the Program
The seventh (and final) step of software design is updating the
program; which can be a never-ending process, as you think of
things which can be improved. It also involves several of the
other steps. Obviously, since we will just be writing PHONENUM
in this article, we can't really update it just yet.
Issue C News 19
The Idea
(Also known, by the more textbook types, as "Defining the
Problem")
The first part of any programming project is the idea for
the program itself. I don't know of any programmers who sit
down and start writing code with no idea of what they will
write. Ideas for programs can strike anytime, anyplace. For
example, I write them down on a sheet/scrap of paper and then,
at some point, copy the good ones into a loose leaf notebook.
Barry is more organized than I am, he carries a Black
Composition book -- the kind that you find in school bookstores
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -