As we know, C doesn't have dynamic scoping, but assuming it did, the program would print 3 4.
In main, a and b are the global ones. a will be set to 2, as we will see that this is what p will return.
In p, called from main, b is still the global one, but a is the one local in p. The local a is set to 0, but will soon disappear. The global b is set to 1. The local p is set to 2, and 2 will be returned. Now the global b is 1.
In q, called from main, a is the global one, but b is the one local in q. Here the global a is set to 3, and the local b is set to 4.
In print, called from q, a is the global one (which has the value 3), and b is the one local in q (which has the value 4).
It is in this last step, inside the function print, that we see a difference from static scoping. With static scoping a and b would be the global ones. With dynamic scoping, we have to look at the chain of calling functions, and in q we find a variable b, which will be the b used inside print.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…