📄 c-lesson.3
字号:
Lesson 2
Data Storage Concepts.
It has been stated that "data + algorithms = programs".
This Lesson deals with with the first part of the addition sum.
All information in a computer is stored as numbers represented using the
binary number system. The information may be either program instructions or
data elements. The latter are further subdivided into several different types,
and stored in the computer's memory in different places as directed by the
storage class used when the datum element is defined.
These types are:
a) The Character.
This is a group of 8 data bits and in 'C' represents either
a letter of the Roman alphabet, or a small integer in the range of 0
through to +255. So to arrange for the compiler to give you a named
memory area in which to place a single letter you would "say":
char letter;
at the beginning of a program block. You should be aware that
whether or not a char is signed or unsigned is dependant
on the design of the processor underlying your compiler.
In particular, note that both the PDP-11, and VAX-11 made by
Digital Equipment Corporation have automatic sign extention of
char.
This means that the range of char is from -128 through to +127
on these machines. Consult your hardware manual, there may be
other exceptions to the trend towards unsigned char as the
default.
This test program should clear things up for you.
/* ----------------------------------------- */
#ident "@(#) - Test char signed / unsigned.";
#include <stdio.h>
main()
{
char a;
unsigned char b;
a = b = 128;
a >>= 1;
b >>= 1;
printf ( "\nYour computer has %ssigned char.\n\n", a == b ? "un" : "" );
}
/* ----------------------------------------- */
Here ( Surprise! Surprise! ) is its output on a machine which has
unsigned chars.
Your computer has unsigned char.
Cut this program out of the news file. Compile and execute it on
your computer in order to find out if you have signed or
unsigned char.
b) The Integers.
As you might imagine this is the storage type in which to store whole
numbers. There are two sizes of integer which are known as short and long.
The actual number of bits used in both of these types is Implementation
Dependent. This is the way the jargonauts say that it varies from computer
to computer. Almost all machines with a word size larger than sixteen bits
have the the long int fitting exactly into a machine word and
a short int
represented by the contents of half a word. It's done this way because
most machines have instructions which will perform arithmetic
efficiently
on both the complete machine word as well as the half-word.
For the
sixteen bit machines, the long integer is two machine words
long,
and the short integer is one.
short int smaller_number;
long int big_number;
Either of the words short or long may be omitted as a default is
provided by the compiler. Check your compiler's documentation
to see
which default you have been given. Also you should be aware
that some
compilers allow the you to arrange for the integers declared
with just
the word "int" to be either short or long. The range for a
short int on
a small computer is -32768 through to +32767, and for a long
int
-4294967296 through to +4294967295.
c) The Real Numbers.
Sometimes known as floating point numbers this number representation
allows us to store values such as 3.141593, or -56743.098. So, using
possible examples from a ship design program you declare floats and
doubles like this:
float length_of_water_line; /* in meters */
double displacement; /* in grammes */
In the same way that the integer type offers two sizes so does the
floating point representation. They are called float and double. Taking
the values from the file /usr/include/values.h the ranges which can be
represented by float and double are:
MAXFLOAT 3.40282346638528860e+38
MINFLOAT 1.40129846432481707e-45
MAXDOUBLE 1.79769313486231470e+308
MINDOUBLE 4.94065645841246544e-324
However you should note that for practical purposes the maximum
number of significant digits that can be represented by a
float
is approximately six and that by a double is twelve. Also you
should
be aware that the above numbers are as defined by the IEEE
floating
point standard and that some older machines and compilers do
not
conform. All small machines bought retail will conform. If you
are
in doubt I suggest that refer to your machine's documentation
for
the whole and exact story!
d) Signed and unsigned prefixes.
For both the character and integer types the declaration can be
preceded by the word "unsigned". This shifts the range so that
0
is the minimum, and the maximum is twice that of the signed
data
type in question. It's useful if you know that it is
impossible
for the number to go negative. Also if the word in memory is
going
to be used as a bit pattern or a mask and not a number the use
of
unsigned is strongly urged. If it is possible for the sign bit
in
the bit pattern to be set and the program calls for the bit
pattern
to be shifted to the right, then you should be aware that the
sign
bit will be extended if the variable is not declared unsigned.
The default for the "int" types is always "signed", and, as
discussed
above that of the "char" is machine dependent.
This completes the discussion on the allocation of data types, except to
say that we can, of course, allocate arrays of the simple types simply by
adding a pair of square brackets enclosing a number which is the size of
the array after the variable's name:
char client_surname[31];
This declaration reserves storage for a string of 30 characters plus the
NULL character of value zero which terminates the string.
Structures.
Data elements which are logically connected, for example - to use the
example alluded to above - the dimensions and other details about a
sea
going ship, can be collected together as a single data unit called a
struct. One possible way of laying out the struct in the source code
is:
struct ship /* The word "ship" is known as the structure's "tag". */
{
char name[30];
double displacement; /* in grammes */
float length_of_water_line; /* in meters */
unsigned short int number_of_passengers;
unsigned short int number_of_crew;
};
Note very well that the above fragment of program text does NOT
allocate any storage, it merely provides a named template to
the
compiler so that it knows how much storage is needed for the
structure. The actual allocation of memory is done either like
this:
struct ship cunarder;
Or by putting the name of the struct variable between the "}"
and
the ";" on the last line of the definition. Personally I don't
use this method as I find that the letters of the name tend to
get
"lost" in the - shall we say - amorphous mass of characters
which
make up the definition itself.
The individual members of the struct can have values assigned to
them in this fashion:
cunarder.displacement = 97500000000.0;
cunarder.length_of_water_line = 750.0
cunarder.number_of_passengers = 3575;
cunarder.number_of_crew = 4592;
These are a couple of files called demo1.c & demo1a.c which contain
small 'C' programs for you to compile. So, please cut them out
of the
news posting file and do so.
----------------------------------------------------------------------
#ident demo1.c /* If your compiler complains about this line, chop it out */
#include <stdio.h>
struct ship
{
char name[31];
double displacement; /* in grammes */
float length_of_water_line; /* in meters */
unsigned short int number_of_passengers;
unsigned short int number_of_crew;
};
char *format = "\
Name of Vessel: %-30s\n\
Displacement: %13.3f\n\
Water Line: %5.1f\n\
Passengers: %4d\n\
Crew: %4d\n\n";
main()
{
struct ship cunarder;
cunarder.name = "Queen Mary"; /* This is the bad line. */
cunarder.displacement = 97500000000.0;
cunarder.length_of_water_line = 750.0
cunarder.number_of_passengers = 3575;
cunarder.number_of_crew = 4592;
printf ( format,
cunarder.name,
cunarder.displacement,
cunarder.length_of_water_line,
cunarder.number_of_passengers,
cunarder.number_of_crew
);
}
----------------------------------------------------------------------
Why is the compiler complaining at line 21?
Well C is a small language and doesn't have the ability to allocate
strings to variables within the program text at run-time. This
program shows the the correct way to copy the string "Queen
Mary",
using a library routine, into the structure.
----------------------------------------------------------------------
#ident demo1a.c /* If your compiler complains about this line, chop it out */
#include <stdio.h>
/*
** This is the template which is used by the compiler so that
** it 'knows' how to put your data into a named area of memory.
*/
struct ship
{
char name[31];
double displacement; /* in grammes */
float length_of_water_line; /* in meters */
unsigned short int number_of_passengers;
unsigned short int number_of_crew;
};
/*
** This character string tells the printf() function how it is to output
** the data onto the screen. Note the use of the \ character at the end
** of each line. It is the 'continue the string on the next line' flag
** or escape character. It MUST be the last character on the line.
** This technique allows you to produce nicely formatted reports with all the
** ':' characters under each other, without having to count the characters
** in each character field.
*/
char *format = "\n\
Name of Vessel: %-30s\n\
Displacement: %13.1f grammes\n\
Water Line: %5.1f metres\n\
Passengers: %4d\n\
Crew: %4d\n\n";
main()
{
struct ship cunarder;
strcpy ( cunarder.name, "Queen Mary" ); /* The corrected line */
cunarder.displacement = 97500000000.0;
cunarder.length_of_water_line = 750.0;
cunarder.number_of_passengers = 3575;
cunarder.number_of_crew = 4592;
printf ( format,
cunarder.name,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -