我们接着上一篇博客来看。
让我们来看一段代码,
int add(a, b){
int c = a + b;
a += 100;
return c;
}
int main(){
int a = 10, b = 20, c;
c = add(a, b);
printf("%d %d", c, a);
system("pause");
return 0;
}
这个代码打印出来的结果到底是什么样子的呢?
这里打印出来的a的值到底是多少呢?110?10?
在这里我们要引出来两个概念。
栈 栈帧
(1)什么是栈呢?
这个概念可能没有学习数据结构的人可能了解不太多。栈是一种只能在一段插入和删除的操作的特殊线性表。他按照先进后出的原则存储数据,先进入的数据被压在栈底,最后的数据在栈顶。需要读数据的时候从栈顶弹出一个数据。
(2)什么又是栈帧呢?
栈帧表示程序的函数的调用记录,而栈帧又是记录在栈上面。通俗的说,一个栈分了n个记录块,每一个记录块就是一个栈帧。一个栈1兆空间,而一个栈帧大概88个字节,这个是根据编译器的与不同来决定的。
那么函数在运行时,栈帧是如何记录的呢?
根据上面的代码,我们来看一下这个图,根据图来理解。.
首先呢,先执行了main函数,为他分配了一个栈帧,紧接着在main函数里面又调用了add函数,在add函数里面实现了a+b,将他俩的和返回给,main函数里面的c ,此时,add函数占用的栈帧就释放了,所以a还是打印的是10 而不是110.
**break continue goto return 的区别 **
break: 在for循环中,跳到表达式三在继续开始执行。在do while 和while中,结束循环,执行循环后面的语句。一般都会与if语句配合使用,当满足某个条件时 跳出循环在开关语句中,可以使程序跳出switch,继续执行switch之后的语句,如果没有break语句,它将成为一个死循环无法退出。
continue:跳到循环头 开始下一个循环。也就是说它不执行continue后面的语句,然后开始下一次循环。
return:return并不是专门跳出循环的,它是用来结束一个方法,一旦在循环体内遇到return,他就会结束这个方法,当然,循环也就自然而然的结束了。
与break,continue 不同的是,return不论位于多少层循环之内,他都直接结束这个方法。
再来说一说goto:
goto语句也称为无条件转移语句,其一般格式如下: goto 语句标号; 其中语句标号是按标识符规定书写的符号, 放在某一语句行的前面,标号后加冒号(?。语句标号起标识语句的作用,与goto 语句配合使用。
如: label: i++;
loop: while(x<7);
goto:loop
C语言不限制程序中使用标号的次数,但各标号不得重名。goto语句的语义是改变程序流向, 转去执行语句标号所标识的语句。
goto语句通常与条件语句配合使用。可用来实现条件转移, 构成循环,跳出循环体等功能。
但是,在结构化程序设计中一般不主张使用goto语句, 以免造成程序流程的混乱,使理解和调试程序都产生困难。