⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hungnote.txt

📁 C语言库函数的源代码,是C语言学习参考的好文档。
💻 TXT
📖 第 1 页 / 共 2 页
字号:
qualifiers when not needed, even if they seem valuable.


Naming Rules for Procedures

  Unfortunately, the simple notion of qualified typed tags does not work well
for procedure names. Some procedures do not take parameters or do not return
values. The scopes of procedure names tend to be large. The following set of
special rules for procedures has worked quite satisfactorily:

  1.  Distinguish procedure names from other names by punctuation, for
      example by always starting with a capital letter (typed tags of other
      quantities are in lower case). This alleviates the problem caused by
      the large scope.
  2.  Start the name with the tag of the value that is returned, if any.
  3.  Express the action of the procedure in one or two words, typically
      transitive verbs. The words should be punctuated for easy parsing by
      the reader (a common legal method of punctuation is the use of capital
      initials for every word).
  4.  Append the list of tags of some or all of the formal parameters if it
      seems appropriate to do so.

  The last point is contrary to the earlier remarks on data structure naming.
When the parameters to a procedure are changed, typically all uses of the
procedure will have to be updated. There is an opportunity during the update
to change the name as well, in fact the name change can serve as a useful
check that all occurrences have been found. With data structures, the
addition or change of a field will not have an effect on all uses of the
changed structure type. Typically, if a procedure has only one or two
parameters, the inclusion of the parameter tags will really simplify the
choice of procedure name.

  Some examples for procedure names are the following:

InitSy:      Takes an sy as its argument and initializes it.
OpenFn:      fn is the argument. The procedure will "open" the fn.
             No value is returned.
FcFromBnRn:  Returns the fc corresponding to the bn,rn,pair given.
             (The names cannot tell us what the types sy, fn, fc,
             etc., are.)

 The following is a list of standard type constructions. (X and Y stand for
arbitrary tags. According to standard punctuation the actual tags are
lowercase.)

pX        pointer to X
dX        difference between two instances of type X.  X + dX
          is of type X.
cX        count of instances of type X.
mpXY      an array of Y's indexed by X.  Read as "map from X to Y."
rgX       an array of X's.  read as "range X."  The indices of the array
          are called:
iX        indent of the array rgX.
dnX       (rare) an array indexed by type X.  The elements of the array
          are called:
eX        (rare) element of the array dnX.
grpX      a group of X's stored one after another in storage.  Used when
          the X elements are of variable size and standard array indexing
          would not apply.  Elements of the group must be referenced by
          means other then direct indexing.  A storage allocation zone,
          for example, is a grp of blocks.
bX        relative offset to a type X.  This is used for field
          displacements in a data structure with variable size fields.
          The offset may be given in terms of bytes or words, depending
          on the base pointer from which the offset is measured.

  Where it matters, quantities named mp, rg, dn, or grp are actually pointers
to the structures described above.

      cbX       size of instances of X in bytes
      CwX       Size of instances of X in words

  One obvious problem with the constructions is that they make the parsing of
the types ambiguous. Is pfc a tag of its own or is it a pointer to an fc?
Such questions (just as many others) can be answered only if one is familiar
with the specific tags that are used in a program.

  The following are standard qualifiers. (The letter X stands for any type
tag. Actual type tags are in lowercase.)

XFirst       the first element in an ordered set (interval) of X values.
XLast        the last element in an ordered set of X values.  XLast is the
             upper limit of a closed interval, hence the loop continuation
             condition should be:  x<=xLast
XLim         the strict upper limit of an ordered set of X values.  Loop
             continuation should be:  x<xLim
XMax         strict upper limit for all X values (excepting Max, Mac,
             and Nil) for all other x:  x<xMax.  If x values start with
             x=0, xMax is equal to the number of different x values.
             The allocated length of a dnx vector, for example, will be
             typically xMax.
XMac         the Current (as opposed to constant or allocated) upper limit
             for all x values.  If x values start with 0, xMac is the
             current number of X values.  To iterate through a dnx array,
             for example:
                for x=0 step 1 to xMac-1 do ... dnx[x] ...
                or
                for ix=0 step 1 to ixMac-1 do ... rgx[ix] ...
XNil         a distinguished Nil value of type X.  The value may or may not
             be 0 or -1.
XT           temporary X.  An easy way to qualify the second quantity of a
             given type in a scope.


SOME COMMON PRIMITIVE TYPES

f    flag (boolean, logical).  If qualifier is used, it should describe the
     true state of the flag.  Exception:  the constants fTrue and fFalse.
w    word with arbitrary contents.
ch   character, usually in ASCII text.
b    byte, not necessarily holding a coded character, more akin to w.
     Distinguished from the b constrictor by the capital letter of the
     qualifier in immediately following.
sz   pointer to first character of a zero terminated string.
st   pointer to a string.  First byte is the count of characters cch.
h    pp (in heap).

  The following partial example of an actual symbol table routine illustrates
the use of the conventions in a "real life" situation. The purpose of this
example is not to make any claims about the code itself, but to show how the
conventions can help us learn about the code. In fact, some of the names in
this routine are standard.

 1   #include "sy.h"
 2   Extern int *rgwDic;
 3   extern int bsyMac;
 4   struct SY *PsySz(sz)
 5   char sz[];
 6      {
 7      char *pch;
 8      int cch;
 9      struct SY *psy, *PsyCreate();
10      int *pbsy;
11      int cwSz;
12      unsigned wHash=0;
13      pch=sz;
14      while (*pch!=0
15         wHash=(wHash<<5)+(wHash>>11+*pch++;
16      cch=pch-sz;
17      pbsy=&rgbsyHash[(wHash&077777)%cwHash];
18      for (; *pbsy!=0; pbsy = &psy->bsyNext)
19         {
20         char *szSy;
21         szSy= (psy=(struct SY *)&rgwDic[*pbsy])->sz;
22         pch=sz;
23         while (*pch==*szSy++)
24            {
25            if (*pch++==0)
26               return (psy);
27            {
28         }
29      cwSz=0;
30      if (cch>=2)
31         cwSz=(cch-2/sizeof(int)+1;
32      *pbsy=(int *)(psy=PsyCreate(cwSY+cwSz))-rgwDic;
33      Zero((int *)psy,cwSY);
34      bltbyte(sz, psy->sz, cch+1);
35      return(psy);
36      }

  The tag SY is the only product specific type in this routine. The
definition of SY is found in the include file sy.h (fair enough). The type
name itself is in all capitals, a common convention.

  Line 2 - says that there is an array of words, which is called
Dic(tionary). Remember that since Dic is a qualifier, it is named
traditionally.

  Line 3 - is the offset pointing beyond the last sy (see b constructor + Mac
standard qualifier.) One has to guess at this time that this is used for
allocating new sy's. The "base" of the offset would also have to be guessed
to be rgwDic. Actually, the name grpsy would have been better instead of
rgwDic, from this local perspective. In the real program, the rgwDic area is
used for a number of different purposes, hence the "neutral" name.

  Line 4 - is a procedure declaration. Procedure returns a pointer to an SY
as the result. The parameter must be a zero terminated string.

  Lines 7-12 - declare quantities. The usages should be clear from the names.
For example, cwSz is the number of words in some string (probably the
argument), pbsy is a pointer to an offset of an sy (p constructor + b
constructor). The only qualifier used here is in wHash - the hash code.

  Line 13 - pch will be a pointer to the first character of sz.

  Line 16 - cch is the count of characters (c constructor) ostensibly,
in sz.

  Line 17 - cwHash is the number of words in the hash table (I would have
called it ibsyMax). In a way, the qualifier on rgbsyHash could be omitted,
but it helps identifying the hash table in external contexts.

  Lines 17-18 - note the opportunities for dimensional checking:

      pbsy =  rgbsy[...] follows from pX = &rgX[...]
      pbsy =  psy->bsy Next follows from pX=&pY->X; or pX = &Y.X

So even the use of -> instead of . follows from local context. The p on the
left hand side signals the need for the & on the right.

  Line 20 - introduces a new sz, qualified to distinguish it from the
argument. The qualifier, very appropriately, is the source of the datum, Sy.

  Line 23 - given the use of szSy in this line, the name pchSy would have
been a little more appropriate. No harm done, however.

  Lines 29-31 - this strange code has to do with the fact that the
declaration of SY includes 2 bytes of sz, so that cwSz is really the number
of words in the sz-2 bytes! This should deserve a comment or at least a
qualifier M2 (minus 2) or the like. cwSY is the length of the SY structure in
words. The all caps qualifier is not strictly standard, but it helps to
associate the quantity with the declaration of SY, rather than with any
random sy instance.

  PsyCreate is a good procedure name; PsyCreateCw would have been even
better. In line 32 we can also see an example of dimensional checking: while
we have a psy inside the parenthesis, we need a bsy for the left side (*pbsy
=bsy!) so we subtract the "base" of the bsy from the psy

      bX + base = pX; hence:  bX = pX - base.

  In closing, it is evident that the conventions participated in making the
code more correct, easier to write and easier to read.  Naming conventions
cannot guarantee "good" code however, only the skill of the programmer can.

Charles Simonyi
Microsoft Corporation

**************

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -