我有以下代码片段,我必须分析输出结果:
#include <stdio.h>
void f(int d);
int a = 1, b = 2, c = 3, d = 4;
int main(){
int a = 5, c = 6;
f(a);
f(b);
f(c);
printf("%d %d %d %d\n",a,b,c,d);
return 0;
}
void f(int d){
static int a = 0;
a = a + 7;
b = a + d;
c++;
d--;
printf("%d %d %d %d\n",a,b,c,d);
}
我得到的输出如下:
7 12 4 4
15 26 5 11
21 27 6 5
5 27 6 4
这真让我困惑。我注意到在所有3个函数调用中,全局声明的a
都会受到分配的影响,并且printf()
来自main()
的{{1}}正在打印a
中声明的main()
。但是,我不确定其余变量的行为。这是未定义的行为还是实际上有意义?
答案 0 :(得分:3)
int a = 1, b = 2, c = 3, d = 4;
---&gt;全局变量
int main(){
int a = 5, c = 6; ---> Shadows the global `a` and `c`
...
void f(int d){
static int a = 0; ---> local static variable visible only inside `f`
...
答案 1 :(得分:2)
这与C的标识符范围有关。声明的范围是C程序的区域,该声明在该区域中可见。有六个范围:
您的程序中发生的事情称为名称重载 - 同一标识符一次可能与多个程序实体相关联的情况。 C中有5个重载类(aka名称空间):
在C中,块开头的声明可以隐藏块外的声明。 对于一个隐藏另一个声明的声明,声明的标识符必须相同,必须属于同一个重载类,并且必须在两个不同的作用域中声明,其中一个包含另一个。
考虑到这一点,在您的代码中,本地a
和c
隐藏a
中的全局c
和main()
以及a
f()
隐藏了全局a
。所有其他引用都在操纵全局变量。
答案 2 :(得分:1)
void f(int d){
**static int a = 0;**
a = a + 7;
b = a + d;
c++;
d--;
printf("%d %d %d %d\n",a,b,c,d);
}
你说的是全局 int a 和全局无效函数 f 但你也声明了静态变量 每当函数调用时,函数就是引用函数的变量。 如果你想避免这个问题,你应该创建一个全局变量的指针,并引用一个指向地址的值全局变量。 如您所知,静态变量保持其最后一个值直到程序结束。
除非由malloc分配,否则每个函数的变量都将完全放在“Stack”中。 全局变量是“堆”。 我不确定,但是如果你反汇编你的程序,静态值将会叠加 并用PUSH和POP指令处理。
答案 3 :(得分:0)
在C / C ++中,给定范围内的标识符从声明之后的开始影响外部范围中的标识符。
以下示例演示了这一点:
#include <stdio.h>
const char a[] = "a";
static const char b[] = "b";
void test(const char * arg)
{
const char c[] = "c1";
printf("1-. a=%s b=%s c=%s arg=%s\n", a,b,c,arg);
const char a[] = "a1";
static const char b[] = "b1";
// arg is present in this scope, we can't redeclare it
printf("1+. a=%s b=%s c=%s arg=%s\n", a,b,c,arg);
{
const char a[] = "a2";
const char b[] = "b2";
const char arg[] = "arg2";
const char c[] = "c2";
printf("2-. a=%s b=%s c=%s arg=%s\n", a,b,c,arg);
{
static const char a[] = "a3";
const char b[] = "b3";
static char arg[] = "arg3";
static const char c[] = "c3";
printf("3. a=%s b=%s c=%s arg=%s\n", a,b,c,arg);
}
printf("2+. a=%s b=%s c=%s arg=%s\n", a,b,c,arg);
}
printf("1++. a=%s b=%s c=%s arg=%s\n", a,b,c,arg);
}
int main(void)
{
test("arg");
return 0;
}
输出:
1-. a=a b=b c=c1 arg=arg
1+. a=a1 b=b1 c=c1 arg=arg
2-. a=a2 b=b2 c=c2 arg=arg2
3. a=a3 b=b3 c=c3 arg=arg3
2+. a=a2 b=b2 c=c2 arg=arg2
1++. a=a1 b=b1 c=c1 arg=arg
答案 4 :(得分:0)
这个输出实际上是有道理的。
在C / C ++中,给定范围内的标识符优先于外部范围中的标识符。在这种情况下,在函数main中,变量a和c将用作局部变量,其余b和d用作全局变量。类似地,在函数void f(int d)
中,d是传递的参数,每当调用函数时,a将用作静态,b和c将用作全局变量。
因此将计算输出。
但是您显示的输出不正确。正确的输出必须是:
7 12 4 4
14 26 5 11
21 27 6 5
5 27 6 4