我的CS教授给了我们这个任务。基本上我们有两个未初始化的全局指针*min_ptr, *max_ptr
。我们正在编写这个void spray_paint( char *x, int sz, char tok, char *t )
函数,它将tok的值放入内存中从x
到x+sz-1
的某个位置。 char *t
只是用于调试目的的随机事物。 *min_ptr, *max_ptr
用于跟踪我们打印的内容的范围。但是,我在初始化前两个指针时遇到了问题。起初,我试图检查它们是否被初始化为NULL,但是我意识到它们在C99之后默认只被初始化为NULL,而我的教授说如果没有指定你就不能假设它们被初始化为NULL,并且我们只能访问void spray_paint( char *x, int sz, char tok, char *t )
,而不能访问代码中的任何其他位置。无论如何都要检查两个全局指针是否已初始化?或者,无论如何在第一次调用子程序时初始化它们,并且永远不再执行它?
char *min_ptr, *max_ptr;
void spray_paint( char *x, int sz, char tok, char *t )
{
char *marker = x + 3;
char *painter = x;
int k;
//if (!min_ptr || !max_ptr)
if (*marker != '~')
{
*marker = '~';
min_ptr = x;
max_ptr = x + sz - 1;
}
for (k = sz - 1; k >= 0; k--)
{
*(painter+k) = tok;
if ((unsigned long) x < (unsigned long) min_ptr)
min_ptr = x;
else if ((unsigned long) x > (unsigned long) max_ptr)
max_ptr = x;
}
printf("%s\n",t);
printf("\n");
}
一个想法是在内存中找到一个位置,让子程序第一次放置一些奇怪的东西,即*marker
,我们只需要检查是否有这么奇怪的事情或者不知道以前是否调用过子程序。这导致了另一个问题,即使在子程序终止后,一个不返回任何内容的子程序是否可以进行一些更改?我在Xcode上用C尝试过,但问题是要么我没有访问我选择的随机位置,要么我不知道应该在哪里选择不会影响程序的位置并赢了其他意外操作不会改变。
答案 0 :(得分:6)
未显式初始化的全局变量(和静态变量)对于算术类型保证为0
,对于指针类型保证为空指针。自C89以来,情况确实如此。
如果没有显式初始化具有静态存储持续时间的对象,则会隐式初始化它,就像每个具有算术类型的成员都被赋值为0而每个具有指针类型的成员都被赋予空指针常量。如果没有显式初始化具有自动存储持续时间的对象,则其值是不确定的。
答案 1 :(得分:2)
替换
char *min_ptr, *max_ptr;
通过
char *min_ptr = 0, *max_ptr = 0;
您无法验证指针是否已初始化,但通过测试其值是否为NULL。
答案 2 :(得分:1)
您可以使用静态变量。
void spray_paint( char *x, int sz, char tok, char *t )
{
static int initialized = 0;
if (!initialized)
{
initialized = 1;
min_ptr = x;
max_ptr = x;
}
// ...
}