[英]declaration of variables with same name as global,local and static
I have the following code snippet and I have to analyse what the output will be: 我有以下代码片段,我必须分析输出将是什么:
#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);
}
The output I've got is as follows: 我得到的输出如下:
7 12 4 4
15 26 5 11
21 27 6 5
5 27 6 4
This really baffled me. 这真让我困惑。 I noticed that in all 3 function calls the globally declared
a
suffers the assignment and that in the printf()
from main()
body the a
declared in main()
is printed. 我注意到,在所有3个函数调用的全局声明
a
遭受分配,并且在printf()
从main()
体的a
中声明main()
打印。 However, I am not sure about the behaviour of the rest of the variables. 但是,我不确定其余变量的行为。 Is this undefined behaviour or it actually makes sense?
这是未定义的行为还是实际上有意义?
int a = 1, b = 2, c = 3, d = 4;
---> Global variables --->全局变量
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`
... ...
This is related to C's identifier scopes. 这与C的标识符范围有关。 The scope of a declaration is the region of the C program over which that declaration is visible.
声明的范围是C程序的区域,该声明在该区域中可见。 There are six scopes:
有六个范围:
What happens in your program is known as overloading of names - a situation in which the same identifier may be associated to more than one program entity at a time. 程序中发生的事情称为名称重载 - 同一标识符一次可能与多个程序实体相关联的情况。 There are 5 overloading classes in C (aka namespaces):
C中有5个重载类(aka名称空间):
In C, declarations at the beginning of a block can hide declarations outside the block. 在C中,块开头的声明可以隐藏块外的声明。 For one declaration to hide another, the declared identifiers must be the same, must belong to the same overloading class, and must be declared in two distinct scopes, one of which contains the other.
对于一个隐藏另一个声明的声明,声明的标识符必须相同,必须属于同一个重载类,并且必须在两个不同的作用域中声明,其中一个包含另一个。
With this in mind, in your code, local a
and c
hide global a
and c
in main()
, and a
in f()
hides global a
. 考虑到这一点,在你的代码,当地
a
和c
隐藏全局a
和c
中main()
和a
在f()
隐藏了全球a
。 All other references are manipulating the global variables. 所有其他引用都在操纵全局变量。
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);
}
That's right you declared global int a and global void function f but also you have declared static variable a Whenever function has called, function is refering a variable of function. 这是正确的你声明全局int a和全局void函数f但你已经声明了静态变量a每当函数调用时,函数就是引用函数的变量。 if you want to avoid this problem, you should make a pointer of global variable, and refering a pointed address's value global variable.
如果你想避免这个问题,你应该创建一个全局变量的指针,并引用一个指向地址的值全局变量。 As you know static variable is keep their last value until end of program.
如您所知,静态变量保持其最后一个值直到程序结束。
each function's variable is exactly going to placed in "Stack" unless allocated by malloc. 除非由malloc分配,否则每个函数的变量都将完全放在“堆栈”中。 And global variable is "Heap".
全局变量是“堆”。 I am not sure but if you disassembly your program, static value a would go to stack and treated with PUSH and POP instruction.
我不确定,但是如果你反汇编你的程序,静态值a会堆叠并用PUSH和POP指令处理。
In C/C++, the identifiers in a given scope shadow the identifiers in the outer scope from the point of declaration onwards . 在C / C ++中,给定范围内的标识符从声明点开始影响外部范围中的标识符。
The following example demonstrates this: 以下示例演示了这一点:
#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;
}
Output: 输出:
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
This output actually makes sense. 这个输出实际上有意义。
In C/C++, the identifiers in a given scope are given preference over the identifiers in the outer scope. 在C / C ++中,给定范围中的标识符优先于外部范围中的标识符。 In this case in the function main, variables a and c will be used as local variables and rest b and d as global variables.
在这种情况下,在函数main中,变量a和c将用作局部变量,其余b和d用作全局变量。 Similarly, in the function
void f(int d)
, d is the passed parameter, a will be used as static whenever the function is called, b and c will be used as global variables. 类似地,在函数
void f(int d)
,d是传递的参数,每当调用函数时,a将用作静态,b和c将用作全局变量。 Hence the output will be calculated. 因此将计算输出。
However you have shown the incorrect output. 但是,您显示的输出不正确。 Correct output must be :
正确的输出必须是:
7 12 4 4 14 26 5 11 21 27 6 5 5 27 6 4
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.