解析docx C语言,C语言面试深度解析.docx

C语言面试深度解析

:概念定义篇 1.1、局部变量能否和全局变量重名? 解答: 能。在局部变量的作用域内,局部变量会屏蔽掉同名的全局变量。此时若需要使用全局变量,需要使用”::”符号(linux中必须使用g++编译,使用gcc时并不识别域操作符::)。 深度解析: C语言中有“作用域”的概念。譬如全局变量作用域为整个文件(准确的说是定义该全局变量的文件中该变量定义/声明之后的部分。只不过一般情况下全局变量都在文件头部定义,因此说全局变量为文件作用域。),局部变量为代码块作用域。 所谓代码块作用域,代码块是指用一对大括号{}括起来的部分(譬如一个函数的函数体,for循环的循环体等)。也就是说局部变量的作用域其实是定义这个局部变量的代码块中该变量定义体之后的部分。 这样看来,至少得到以下两个结论: ? (1)变量的作用域是有大有小的 ? (2)变量的作用域是有重叠部分的。譬如在一个函数内,该函数的局部变量和整个文件的全 局变量都覆盖这个作用域,这就是作用域的重叠。 重叠作用域中,如果全局变量名和局部变量名不同不会造成困扰。因为我们可以很容易的通过变量名来区分两个变量(我们班有个叫旺财的,别人班有个叫富贵的,我叫旺财你肯定知道我要找的是谁吧!)。但是在两个变量名相同时要怎么办呢(我们班有个旺财,隔壁班也有个旺财,我在走廊里喊一声旺财,你觉得我在叫谁···)? 这种情况逻辑学上叫二义性(ambiguity)。即有两种可能的解释,却没有任何区分的方法。怎么办呢?人为规定嘛。C语言规定:在变量作用域重叠时,作用域为小范围的变量覆盖大范围的变量。譬如函数内有个局部变量var,文件内有个全局变量var。则在该函数内部(准确的说是函数内部var局部变量定义体之后的部分),你使用var访问的是var局部变量,此处全局变量var被掩蔽(要想在此处访问全局变量var,对于C++可以使用::符号,而C语言中则没有域操作符::)1.2、堆栈溢出一般是什么原因导致的???解答:堆栈溢出一般都是由堆栈越界访问导致的。例如函数内局部变量数组越界访问,或者函数内局部变量使用过多,超出了操作系统为该进程分配的栈的大小也会导致堆栈溢出。?深度解析:? 首先要区分清楚堆、栈、堆栈这几个名词。堆(heap)和栈(stack)是两种不同的内存管理机制。? 堆被称为动态内存,由堆管理器(系统里的大人物,山高皇帝远不用去管它)管理,程序中可以使用malloc函数来(向堆管理器)申请分配堆内存,使用完后使用free函数释放(给堆管理器回收)。堆内存的特点是:在程序运行过程中才申请分配,在程序运行中即释放(因此称为动态内存分配技术)。? 栈是C语言使用的一种内存自动分配技术(注意是自动,不是动态,这是两个概念),自动指的是栈内存操作不用C程序员干预,而是自动分配自动回收的。C语言中局部变量就分配在栈上,进入函数时局部变量需要的内存自动分配,函数结束退出时局部变量对应的内存自动释放,整个过程中程序员不需要人为干预。? 堆栈这个词纯粹是用来坑人的。堆就是堆(heap),栈就是栈(stack),根本没有另外一种内存管理机制叫堆栈。大多数时候有人说起堆栈,其实他想说的是栈,以前早些的时候,这方面的命名并不是特别准确。(别人说堆栈的时候,大家知道他其实想说的是栈就行了,自己就不要再用这个不准确的词了)。? 既然堆和栈都是用来管理内存的机制,使用时就有一定的规则。无视规则的错误使用(C语言设计时赋予了程序员很大的自由度,所以有些错误语言本身是不会检查的,全凭程序员自己把握。)就可以导致一些内存错误,如内存泄漏、溢出错误等。 内存泄漏主要发生在堆内存使用中。譬如我们使用malloc申请了内存,使用过后并未释放而丢弃了指向该内存的指针(这个指针是这段内存的唯一记录,程序中释放该段内存都靠这个指针了),那么这段堆内存就泄漏掉了(堆管理器以为程序还在使用,所以不会将这段内存再次分配给别的程序)。必须等到这个程序彻底退出后,系统回收该程序所使用的所有资源(申请的内存,使用的文件描述符等)时这些泄漏的内存才重新回到堆管理器的怀抱。? 内存溢出在堆和栈中都有可能发生。参见章节示例1_2_stack_overflow.c中的8个示例函数,其中前三个函数与堆溢出有关,后五个函数与栈溢出有关。?? 函数heap_overflow中使用malloc申请了16字节动态内存,然后尝试去读写这16个内存之中的第n个。三个测试分别给n赋值9,99和9999999,得到的结果很有意思(见程序后面的注释,大家也可以自己编译运行测试),现在我们来探讨其中的原理。? n等于9的时候没什么好说的,本该正确运行,这个相信大家没有异议。n等于99的时候······竟然也

你可能感兴趣的:(解析docx,C语言)