程序员招聘笔试面试题第一期(程序设计基础——变量)

程序设计基础—变量

  • 一、知识要点归纳
    • 1.C语言数据类型
    • 2.变量的作用域和变量在内存中的存储方式
      • a)局部变量和全局变量
      • b)变量的存储类别(auto、register、extern、static)
      • c)内存组织结构
  • 二、面试真题及解析
    • 面试题1
    • 面试题2
    • 面试题3
    • 面试题4
    • 面试题5
    • 面试题6
    • 面试题7

一、知识要点归纳

1.C语言数据类型

程序员招聘笔试面试题第一期(程序设计基础——变量)_第1张图片

2.变量的作用域和变量在内存中的存储方式

a)局部变量和全局变量

变量的作用域是指变量的有效范围。在一个程序中可以有多个变量,根据变量定义的位置,可分为局部变量和全局变量。

局部变量:定义在函数内部,它的作用域仅限于所定义的函数内
全局变量:在所有函数之外定义的变量称为全局变量,它的作用域从定义变量的位置到本源程序结束

b)变量的存储类别(auto、register、extern、static)

1.auto:自动变量,在缺省的情况下,编译器会默认所有局部变量为自动变量,当定义局部变量时未初始化,系统会给予其垃圾值。

2.register:寄存器变量,变量值存放在CPU内部寄存器中,存取速度最快,通常只有需要频繁使用的变量,将其定义为寄存器变量。重要的是,只有局部自动变量和函数形参才可以定义为寄存器变量。

3.extern:外部变量
使用extern声明变量主要有两个作用:一是在函数中提前使用全局变量(提前声明),二是使用其他源文件中的全局变量。

extern int n;//声明一个全局变量n

要注意变量声明和定义的区别,变量定义需要为变量分配相应的存储空间,而变量声明则不需要,只是对欠你们已经定义的变量进行声明,其作用就是 可以在变量未定义之前,先行使用变量,但变量一定是要定义的。 重要的是,声明变量的同时不能初始化。
例如:

extern int a;//声明一个全局变量a
int a;//定义一个全局变量a
extern int a = 1;//因为初始化了,所以这里的extern不是声明变量,而是定义以恶搞全局变量a
int a = 0;//定义一个全局变量a并初始化
#include

int n = 10;//定义全局变量n,i,j
int i = 20;
int j = 30;
void func(){
    int n;//定义一个局部变量n
    n = 1;

    i = 1;
    extern int j;
    j++;    
}
int main(){
    func();
    printf("n = %d,i = %d,j = %d\n",n,i,j);

    return 0;
}

输出结果为 10,1,31
需要注意的是 局部变量和全局变量是可以同名的 当使用局部变量时 会自动屏蔽全局变量。因为在func函数中 是对全局变量i操作的 所以函数结束以后i的值变为1。extern int j 是声明全局变量j 并不是定义局部变量 所以j++是对全局变量j操作,所以j结果为31。而在func中定义了局部变量n 与全局变量n同名 所以在使用局部变量n时,系统会屏蔽全局变量n,当func函数结束后,局部变量n会被释放,不会改变全局变量的值,两个n的存储空间都不同。

第二种作用 在多个源程序文件中声明全局变量

第一个源文件:extern2.c

#include

extern void fun();//声明其他源文件中的函数

int n;//定义全局变量n 因为n未初始化 存放在内存的静态数据区 值为0

static int m = 1;//定义仅用于本源文件的全局变量m

int main(){
    fun();
    printf("n = %d,m = %d\n",n,m);

    return 0;
}

第二个源文件:extern3.c

#include

extern int n;//声明在其他源文件中的全局变量n

int m = 2;//定义全局变量m
void fun(){
    n+=5;
}

编译时需要将两个源文件同时编译 这样extern2中才能使用extern3中的fun函数。

结果为:n=5,m=1

4.static:静态变量

static可以用来修饰局部变量和全局变量
当static修饰全局变量时,将全局变量的作用域仅限在本源文件中,其他源文件使用extern也无法访问到静态全局变量。 静态全局变量和普通全局变量的区别是静态全局变量只能初始化一次,以防止在其他源文件中被访问。

static修饰局部变量时,改变了局部变量的生命周期和存储空间(原本局部变量存放在栈区,静态局部变量存放在数据段), 一般局部变量在定义其的函数结束后就被释放了,但是静态局部变量,在定义其的函数结束后,并不会被释放,它的生命周期一直持续到本程序结束!但不改变其作用域。
容易出错的是:对于定义时初始化的静态全局变量,初始化仅仅执行一次,对于未初始化的静态局部变量,系统自动给它赋初值0。
例如:

#include

void fun(){
    static int n = 1;//定义静态局部变量n 并初始化为1
    n++;
    printf("%d\n",n);
}

void main(){
    fun();
    fun();
    fun();
}

程序结果为2,3,4
因为n为静态局部变量 所以只初始化一遍。在第二个和第三个fun中 并不会初始化n为1。

c)内存组织结构

程序员招聘笔试面试题第一期(程序设计基础——变量)_第2张图片

二、面试真题及解析

大家可以回忆下上面的知识点 因为变量这块知识点不难 但很杂 我们平时不怎么注意很容易遗忘 所以看完一定要及时回忆复习

面试题1

变量的声明和定义有什么区别?
答:变量定义用于为变量分配内存空间,并且可以为变量赋初值。在一个程序中一个变量只可以定义一次。变量声明可以使用extern,用于向程序表明一个已定义的变量的类型和名字,变量声明不会为该变量分配空间,不能在声明的同时赋初值给变量,那样就是定义一个变量,与正常定义变量是等价的。定义包括声明。

面试题2

简述局部static变量和全局static变量的区别?
答:主要使其作用域不同,静态局部变量只在函数内部和语句块内有效,而静态全局变量在整个C程序文件中都有效,但是其他源文件都不能访问他们!

面试题3

在C语言中,关于静态变量的说法正确的有?
A.静态变量和常量的作用相同
B.函数中的静态变量在函数退出后不被释放
C.静态变量只可以赋值一次,赋值后则不能改变
D.静态全局变量作用域为一个程序的所有源文件

大家可以猜猜选什么,一定要仔细哦

答:选B,因为静态变量的生命周期被改变了 一直到程序结束才会被释放。
而C不是只可以赋值一次,而是在函数中初始化一次以后,多次使用这个函数,只会初始化一次。

面试题4

有以下程序,问 a、b、c和func分别存放在什么地方?

int a;
int b = 10;
int func(){
char c = b;
}

答:a是全局变量并未初始化 所以存放在BSS段中,b是全局变量但初始化了 所以存放在静态数据区,c是在func函数中定义的 是局部变量 存放在栈区,func表示函数代码的地址,该函数存放在代码段中。

面试题5

以下程序的输出结果是?

#include

int fuc(int a);//对fun函数的声明 可以在定义之前使用

void main(void){
	int a = 2;
	int i;
	for(i = 0;i < 3;i++){
		printf("%d\n",fun(a));
	}
}

int fun(int a){
	int b = 0;
	static int c = 3;
	b++;
	c++;
	return(a+b+c);
}
	

答:输出结果是7,8,9
这里面 a是局部变量,i是局部变量,b是局部变量,c是静态局部变量
当在for循环中时 一共使用了三次fun函数,每一次a和b的值都会初始化为原来的值,但是c不会,c只初始化一次。第二次fun函数 c的值是第一次fun函数执行完的值,一次类推!

i = 0: a = 2,b = 1,c = 4 结果为7
i = 1: a = 2,b = 1,c = 5 结果为8
i = 2: a = 2,b = 1,c = 6 结果为9

面试题6

说明栈空间与堆空间的区别?
答:栈空间是向地址扩展的数据结构,采用先进后出的工作方式,是一块连续的内存区域,由编译器自动管理,即由编译器分配内存和释放内存,程序员无法控制。
堆空间是用来存储动态分配变量的内存空间,是向高地址扩展的数据结构,是不连续的内存区域,程序员可以随时分配和释放堆空间中的内存空间,如果不及时释放分配的空间,容易造成内存泄漏。

面试题7

什么是内存泄漏?面对内存泄漏和指针越界,你有哪些方法?你通常采用哪些方法来避免和减少这类错误?
答:在程序中采用动态分配函数来开辟堆空间,使用完之后没有及时释放,一直占据内存空间,导致堆空间耗尽,称之为内存泄漏。

当程序发生内存泄漏和指针越界问题时,首先找到程序中出现错误的位置和原因,常使用的方法如下:
1.通过调试工具和相关窗口查看变量的地址
2.添加一些输出语句显示中间结果
3.注释掉部分代码,看是否还出现错误,从而缩短错误范围

为了避免和减少内存泄漏和指针越界这类错误,可以采用以下基本方法:
1.采用malloc等函数动态分配的空间 在不需要使用时及时通过free函数释放
2.定义指针后一定要初始化,哪怕没有初始化为指向特定的地址空间,也要初始化为NULL。
3.动态分配内存的指针最好不要再次赋值。

—————————————————————————————————

你可能感兴趣的:(c语言)