📄 c-lesson.3
字号:
cunarder.displacement,
cunarder.length_of_water_line,
cunarder.number_of_passengers,
cunarder.number_of_crew
);
}
----------------------------------------------------------------------
I'd like to suggest that you compile the program demo1a.c and execute it.
$ cc demo1a.c
$ a.out
Name of Vessel: Queen Mary
Displacement: 97500000000.0 grammes
Water Line: 750.0 metres
Passengers: 3575
Crew: 4592
Which is the output of our totally trivial program to demonstrate
the use of structures.
Tip:
To avoid muddles in your mind and gross confusion in other minds
remember that you should ALWAYS declare a variable using a name which is
long enough to make it ABSOLUTELY obvious what you are talking about.
Storage Classes.
The little dissertation above about the storage of variables was
concerned with the sizes of the various types of data. There is
just the little matter of the position in memory of the variables'
storage.
'C' has been designed to maximise the the use of memory by allowing you
to re-cycle it automatically when you have finished with it.
A variable defined in this way is known as an 'automatic' one. Although
this is the default behaviour you are allowed to put the word 'auto' in
front of the word which states the variable's type in the definition.
It is quite a good idea to use this so that you can remind yourself
that this variable is, in fact, an automatic one. There are three other
storage allocation methods, 'static' and 'register', and 'const'.
The 'static' method places the variable in main storage for the whole
of the time your program is executing. In other words it kills the
're-cycling' mechanism. This also means that the value stored there
is also available all the time. The 'register' method is very machine
and implementation dependent, and also perhaps somewhat archaic in
that the optimiser phase of the compilation process does it all for
you. For the sake of completeness I'll explain. Computers have a small
number of places to store numbers which can be accessed very quickly.
These places are called the registers of the Central Processing Unit.
The 'register' variables are placed in these machine registers instead
of
stack or main memory. For program segments which are tiny loops the
speed
at which your program executes can be enhanced quite remarkably.
The optimiser compilation phase places as many of your variables into
registers as it can. However no machine can decide which of the
variables
should be placed in a register, and which may be left in memory, so if
your program has many variables and two or three should be register
ones
then you should specify which ones the compiler.
All this is dealt with at much greater detail later in the course.
Pointers.
'C' has the very useful ability to set up pointers. These are memory
cells which contain the address of a data element. The variable name is
preceeded by a '*' character. So, to reserve an element of type char
and
a pointer to an element of type char, one would say.
char c;
char *ch_p;
I always put the suffix '_p' on the end of all pointer variables
simply so that I can easily remember that they are in fact pointers.
There is also the companion unary operator '&' which yields the
address of the variable. So to initialize our pointer ch_p to point
at the char c, we have to say.
ch_p = &c;
Note very well that the process of indirection can procede to any
desired depth, However it is difficult for the puny brain of a normal
human to conceptualize and remember more that three levels! So be
careful
to provide a very detailed and precise commentry in your program if
you put more than two or three stars.
Getting data in and out of your programs.
As mentioned before 'C' is a small language and there are no intrinsic
operators to either convert between binary numbers and ascii
characters or to transfer information to and fro between the
computer's memory and the peripheral equipment, such as terminals or
disk stores.
This is all done using the i/o functions declared in the file stdio.h
which you should have examined earlier. Right now we are going to look
at the functions "printf" and "scanf". These two functions together
with their derivatives, perform i/o to the stdin and stdout files,
i/o to nominated files, and internal format conversions. This means
the conversion of data from ascii character strings to binary numbers
and vice versa completely within the computer's memory. It's more
efficient to set up a line of print inside memory and then to send the
whole line to the printer, terminal, or whatever, instead of
"squirting" the letters out in dribs and drabs!
Study of them will give you understanding of a very convenient way to
talk to the "outside world".
So, remembering that one of the most important things you learn in
computing is "where to look it up", lets do just that.
If you are using a computer which has the unix operating system,
find your copy of the "Programmer Reference Manual" and turn to the
page printf(3S), alternatively, if your computer is using some other
operating system, then refer to the section of the documentation which
describes the functions in the program library.
You will see something like this:-
NAME
printf, fprintf, sprintf - print formatted
output.
SYNOPSIS
#include <stdio.h>
int printf ( format [ , arg ] ... )
char *format;
int fprintf ( stream, format [ , arg ] ... )
FILE *stream;
char *format;
int sprintf ( s, format [ , arg ] ... )
char *s, *format;
DESCRIPTION
etc... etc...
The NAME section above is obvious isn't it?
The SYNOPSIS starts with the line #include <stdio.h>. This tells
you that you MUST put this #include line in your 'C' source code
before you mention any of the routines. The rest of the paragraph
tells you how to call the routines. The " [ , arg ] ... " heiroglyph
in effect says that you may have as many arguments here as you wish,
but that you need not have any at all.
The DESCRIPTION explains how to use the functions.
Important Point to Note:
Far too many people ( including the author ) ignore the fact that
the printf family of functions return a useful number which can be
used to check that the conversion has been done correctly, and that
the i/o operation has been completed without error.
Refer to the format string in the demonstration program above for
an example of a fairly sophisticated formatting string.
In order to fix the concepts of printf in you mind, you
might care to write a program which prints some text in three ways:
a) Justified to the left of the page. ( Normal printing. )
b) Justified to the right of the page.
c) Centred exactly in the middle of the page.
Suggestions and Hint.
Set up a data area of text using the first verse of "Quangle" as data.
Here is the program fragment for the data:-
/* ----------------------------------------- */
char *verse[] =
{
"On top of the Crumpetty Tree",
"The Quangle Wangle sat,",
"But his face you could not see,",
"On account of his Beaver Hat.",
"For his Hat was a hundred and two feet wide.",
"With ribbons and bibbons on every side,",
"And bells, and buttons, and loops, and lace,",
"So that nobody ever could see the face",
"Of the Quangle Wangle Quee.",
NULL
};
/* ----------------------------------------- */
Cut it out of the news file and use it in a 'C' program file called
verse.c
Now write a main() function which uses printf alone for (a) & (b)
You can use both printf() and sprintf() in order to create
a solution for (c) which makes a good use of the capabilities
of the printf family. The big hint is that the string controlling
the format of the printing can change dynamically as program execution
proceeds. A possible solution is presented in the file verse.c which is
appended here. I'd like to suggest that you have a good try at making
a program of you own before looking at my solution.
( One of many I'm sure )
/* ----------------------------------------- */
#include <stdio.h>
char *verse[] =
{
"On top of the Crumpetty Tree",
"The Quangle Wangle sat,",
"But his face you could not see,",
"On account of his Beaver Hat.",
"For his Hat was a hundred and two feet wide.",
"With ribbons and bibbons on every side,",
"And bells, and buttons, and loops, and lace,",
"So that nobody ever could see the face",
"Of the Quangle Wangle Quee.",
NULL
};
main()
{
char **ch_pp;
/*
** This will print the data left justified.
*/
for ( ch_pp = verse; *ch_pp; ch_pp++ ) printf ( "%s\n", *ch_pp );
printf( "\n" );
/*
** This will print the data right justified.
**
** ( As this will print a character in column 80 of
** the terminal you should make sure any terminal setting
** which automatically inserts a new line is turned off. )
*/
for ( ch_pp = verse; *ch_pp; ch_pp++ ) printf ( "%79s\n", *ch_pp );
printf( "\n" );
/*
** This will centre the data.
*/
for ( ch_pp = verse; *ch_pp; ch_pp++ )
{
int length;
char format[10];
length = 40 + strlen ( *ch_pp ) / 2; /* Calculate the
field length */
sprintf ( format, "%%%ds\n", length ); /* Make a format
string. */
printf ( format, *ch_pp ); /* Print line of
verse, using */
} /* generated format
string */
printf( "\n" );
}
/* ----------------------------------------- */
If you cheated and looked at my example before even attempting
to have a go, you must pay the penalty and explain fully why
there are THREE "%" signs in the line which starts with a call
to the sprintf function. It's a good idea to do this anyway!
So much for printf(). Lets examine it's functional opposite - scanf(),
Scanf is the family of functions used to input from the outside world
and to perform internal format conversions from character strings to
binary numbers. Refer to the entry scanf(3S) in the Programmer
Reference Manual. ( Just a few pages further on from printf. )
The "Important Point to Note" for the scanf family is that the
arguments to the function are all POINTERS. The format string has to
be passed in to the function using a pointer, simply because this
is the way 'C' passes strings, and as the function itself has to store
its results into your program it ( the scanf function ) has to "know"
where you want it to put them.
Copyright notice:-
(c) 1993 Christopher Sawtell.
I assert the right to be known as the author, and owner of the
intellectual property rights of all the files in this material,
except for the quoted examples which have their individual
copyright notices. Permission is granted for onward copying,
but not modification, of this course and its use for personal
study only, provided all the copyright notices are left in the
text and are printed in full on any subsequent paper reproduction.
--
+----------------------------------------------------------------------+
| NAME Christopher Sawtell |
| SMAIL 215 Ollivier's Road, Linwood, Christchurch, 8001. New Zealand.|
| EMAIL chris@gerty.equinox.gen.nz |
| PHONE +64-3-389-3200 ( gmt +13 - your discretion is requested ) |
+----------------------------------------------------------------------+
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -