静态变量:
某些变量,比如文件stack.c中定义的变量sp与val以及文件getch.c中定义的变量buf与bufp,它们仅供其所在的源文件中的函数使用,其他函数不能访问。用static声明限定外部变量与函数,可以将其后声明的对象的作用域限定为被编译源文件的剩余部分。通过static限定外部对象,可以达到隐藏外部对象的目的,比如,getch-ungetch复合结构需要共享buf与bufp两个变量,这样buf与bufp必须是外部变量,但这两个对象不应该被getch与ungetch函数的调用者所访问。
要将对象指定为静态存储,可以在正常的对象声明之前加上关键字static作为前提。如果把上述两个函数和两个变量放在一个文件中编译,如下所示:
static char buf[BUFSIZE]; /* ungetch函数使用的缓存区 */
static int bufp = 0; /* 缓存区buf的下一个空闲位置 */
int getch(void){…}
void ungetch(int c){…}
那么其他函数就不能访问变量buf与bufp,因此这两个名字不会和同一程序中的其他文件中的相同的名字相冲突。同样,可以通过把变量sp与val声明为静态类型隐藏这两个由执行栈操作的push与pop函数使用的变量。
外部的static声明通常多用于变量,当然,它也可用于声明函数。通常情况下,函数名字是全局可访问的,对整个程序的各个部分而言都可见。但是,如果把函数声明为static类型,则该函数名除了对该函数声明所在的文件可见外,其他文件都无法访问。
练习4-11
#include <stdio.h>
#include <ctype.h>
#define NUMBER '0' /* signal that a number was found */
int getch(void);
int getop(char s[])
{
int i, c;
static int lastc = 0;
if(lastc == 0)
c = getch();
else
{
c = lastc;
lastc = 0;
}
while((s[0] = c == ' ' || c == '\t')
c = getch();
s[1] = '\0';
if(!isdigit(c) && c != '.')
return c;
i = 0;
if(isdigit(c))
while(isdigit(s[++i] = c = getch()));
if(c == '.')
while(isdigit(s[++i] = c = getch()));
s[i] = '\0';
if(c != EOF)
lastc = c;
return NUMBER;
}
寄存器变量:
register声明告诉编译器,它所声明的变量在程序中使用频率较高。其思想是,将register变量放在机器的寄存器,这样可以使程序更小、执行速度更快。但编译器可以忽略此选项。
register声明的形式如下所示:
register int x;
register char c;
register声明只适用于自动变量以及函数的形式参数。下面是后一种情况的例子:
f(register unsigned m,register long n)
{
register int i;
……
}