我在Hackerrank的program中用C语言完成了这个任务,我在没有声明字符数组'result'为static的情况下解决了这个程序。它返回了一个错误,我的输出与预期输出不匹配。但是当我在数组'result'的声明中插入关键字'static'时,代码就成功运行了。
下面是我的代码片段:
char* timeConversion(char* s)
{
int i;
static char result[100]; // this doesn't work if i remove the word 'static'
if (s[0]=='1' && s[1]=='2' && s[8]=='A')
{
result[0]='0';
result[1]='0';
for (i=2;i<8;i++)
result[i]=s[i];
}
else if (s[0]=='1' && s[1]=='2' && s[8]=='P')
for (i=0;i<8;i++)
result[i]=s[i];
else
{
if (s[8]=='A')
for (i=0;i<8;i++)
result[i]=s[i];
if (s[8]=='P')
{
result[0]=s[0]+1;
result[1]=s[1]+2;
for (i=2;i<8;i++)
result[i]=s[i];
}
}
return result;
}
我不明白,在这里静电有什么用?
3条答案
按热度按时间bf1o4zei1#
两件事:
1.你从你的函数返回一个堆栈分配的数组的地址,如果它不是
static
,你返回的是一个已经不存在的数组的地址,因为通常堆栈上的对象一旦超出作用域就会消失(即当函数返回时)。要从函数返回可由调用代码实际使用的数组,它必须被分配在堆上(即,用malloc
)或者被声明为static
,因为用static
限定符声明的函数中的局部变量在函数返回之后持续存在。1.如果声明了一个没有
static
限定符的变量,但没有显式初始化,那么它只会获取当时内存中已经存在的内容。如果一个局部变量或数组是用
static
限定符声明的,它会被隐式初始化为零,这意味着变量result
可以用解析后的日期/时间值填充,并且保证是一个以空值结尾的字符串,因为数组中所有没有被函数代码填充的元素都已经是零。hs1rzwqc2#
C11 6.2.2标识符的链接(P3):
如果对象或函数的文件作用域标识符声明包含存储类说明符
static
,则标识符具有内部链接。30)脚注:
30)函数声明只有在文件范围内才能包含存储类说明符
static
;参见6.7.1。这意味着
static
变量被声明一次,它的生命周期是整个程序的执行时间,这就是为什么返回静态数组在你的代码中工作正常,这是有意义的。如果您删除
static
关键字,那么数组成为一个局部或自动和局部变量的范围只存在于块或函数中,它是在声明。在您的代码中,您试图返回局部数组,调用undefined behaviour。GCC编译器警告:
nfeuvbwi3#
我不明白,在这里静电有什么用?
static
的两个含义与您的程序相关,摘自C99标准(N1256):1.对象的存储持续时间决定了它的生存期。存储持续时间有三种:静态的、自动的和分配的。分配的存储在7.20.3中描述。
1.对象的生存期是程序执行的一部分,在此期间保证为它保留存储空间。一个对象存在,有一个常数地址,并在其整个生存期内保留其最后存储的值。如果一个对象在其生存期外被引用,其行为是未定义的。当它所指向的对象到达其生存期终点时,指针的值就变得不确定。
1.一个对象,其标识符用外部或内部链接声明,或用存储类说明符static声明,具有静态存储持续时间。它的生存期是程序的整个执行过程,其存储值只在程序启动前初始化一次。
....
10.如果具有自动存储持续时间的对象未显式初始化,则其值不确定。如果具有静态存储持续时间的对象未显式初始化,则:
因此,在您的示例中,
static
指定了result
数组的生存期,并按照上面突出显示的规则初始化了该数组。