C语言面试题

目录

1、*p++和++*p 的区别

2、关键字volatile有什么含意?

3、const 有什么用途?

4、static有什么用途?

5、堆栈溢出一般是由什么原因导致的?

6、如何引用一个已经定义过的全局变量?

7、队列和栈有什么区别?

8、Heap与stack的差别?

9、用宏定义写出swap( x,y),即交换两数

10、写一个“标准”宏,这个宏输入两个参数并返回较小的一个

11、写一个“标准”宏,这个宏输入两个参数并返回较大的一个

12、带参宏与带参函数的区别

13、关键字volatile有什么含意?

14、已知一个数组table,用一个宏定义,求出数据的元素个数。

15、数组和链表的区别?

16、A.c 和B.c两个c文件中使用了两个相同名字的static变量,编译的时候会不会有问题?这两个static变量会保存到哪里(栈还是堆或者其他的)?

17、static全局变量与普通的全局变量有什么区别?

18、static函数与普通函数有什么区别?

19、程序的局部变量存在于栈(stack)中,全局变量和静态变量存在于静态数据区 中,动态申请数据存在于堆( heap)中。

20、用两个栈实现一个队列的功能?要求给出算法和思路!

21、程序输出结果?

22、case 语句之后没有break,所以会执行完所有的条件。


1、*p++++*p 的区别

表达式*p++表示先取出指针p指向的值,然后将指针p向后移动一个位置。即先取值后自增。

而表达式++*p表示先取出指针p指向的值,并将该值加1,然后将指针p指向加1后的位置。即先自增后取值。

#include <stdio.h>
#include<string.h>
int main()
{
	int num[5]={10,20,30,40,50};
	int *pnum = num;//数组名就是数组的首地址
	for(int i=0;i<5;i++) 
	{
		printf("%d\t",*pnum++);  //*pnum++  打印的结果
	}
	printf("\n");
	int *pnum1 = num;
	for(int i=0;i<5;i++)
	{
		printf("%d\t",++*pnum1);  //++*pnum1  打印的结果
	}
	printf("\n");
}

运行结果:

2、关键字volatile有什么含意?

使用volatile修饰的变量,即该变量可能在程序运行过程中被意外修改。这意味着编译器不会对该变量进行优化,每次使用该变量都会去查询内存中的最新值,以确保程序的正确性。volatile关键字通常用于多线程编程中,用来确保多个线程对变量进行操作时的正确性。

3、const 有什么用途?

( 1)用于声明一个常量变量,一旦被定义后就不能再被修改。
( 2 )const 可以修饰函数的参数、返回值,甚至函数 的定义体。被 const 修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。

4、static有什么用途?

在函数内部使用static修饰局部变量时,表示该变量在程序的整个生命周期内只会被初始化一次,并且在函数调用结束后不会被销毁,其值会一直保持。这种特性使得静态局部变量成为一种很有用的工具,可以在多次函数调用之间保持其值。

在全局变量前使用static关键字修饰,表示该全局变量的作用域被限制在当前文件内,其他文件无法访问该变量。通过这种方式可以实现全局变量的封装,避免被其他文件不小心修改。

在函数前使用static修饰时,表示该函数的作用域也被限制在当前文件内,其他文件无法调用该函数。这种方式可以实现函数的封装和隐藏,只允许当前文件内部调用。

1. 限制变量的作用域( static 全局变量);
2. 设置变量的存储域( static 局部变量)。

5、堆栈溢出一般是由什么原因导致的?

  1. 递归调用层次过深:当一个函数递归调用次数过多,堆栈中保存的函数调用信息会超出其分配的内存空间,导致堆栈溢出。

  2. 局部变量占用内存过多:当一个函数中定义的局部变量占用的内存空间过多时,会导致堆栈溢出。

  3. 循环调用:如果两个或多个函数相互调用,且调用次数过多,也可能导致堆栈溢出。

  4. 大规模数据结构:当需要在堆栈中存储大规模数据结构时,可能会超出堆栈的内存限制,导致堆栈溢出

6、如何引用一个已经定义过的全局变量?

可以用引用头文件的方式,也可以用extern关键字,如果用引用头文件方式来引用某个在头文件中声明的全局变理,假定你将那个变量写错了,那么在编译期间会报错,如果你用extern方式引用 时,假定你犯了同样的错误,那么在编译期间不会报错,而在连接期间报错。

7、队列和栈有什么区别?

队列先进先出,栈后进先出。

8、Heap与stack的差别?

存储位置:

Stack:存储在程序的栈中,是一种先进后出的数据结构,使用栈指针来指向栈的顶部。

Heap:存储在程序的堆中,是一种动态分配内存的数据结构,使用指针来访问堆中的数据。

空间大小:

Stack:分配的空间大小固定,在程序编译时就确定了,通常比较小。

Heap:分配的空间大小不固定,可以根据需要动态分配或释放内存,通常比较大。

内存管理:

Stack:由编译器自动管理内存的分配和释放,遵循先进后出的原则。

Heap:需要程序员手动管理内存的分配和释放,容易产生内存泄漏或内存溢出的问题。

生存周期:

Stack:变量的生存周期与其所在函数的调用周期相同,当函数执行结束时,函数中的局部变量会自动被销毁。

Heap:变量的生存周期可以由程序员自行控制,需要手动释放内存,否则会导致内存泄漏

9、用宏定义写出swap( x,y),即交换两数

#define swap(x, y) (x)=(x)+(y);(y)=(x)–(y);(x)=(x)–(y);

10、写一个“标准”宏,这个宏输入两个参数并返回较小的一个

#define Min(X, Y) ((X)>(Y)?(Y):(X))

11、写一个“标准”宏,这个宏输入两个参数并返回较大的一个

#define Min(X, Y) ((X)<(Y)?(Y):(X))

12、带参宏与带参函数的区别

13、关键字volatile有什么含意?

用于告诉编译器,该变量随时可能发生变化,不应该进行优化,而是应该时刻从内存中读取最新的值。这通常用于多线程并发编程中,可以防止编译器对变量进行优化,确保程序能够正确地访问共享的变量。volatile关键字可以保证变量的可见性和有序性。

14、已知一个数组table,用一个宏定义,求出数据的元素个数。

#define NTBL(table) (sizeof(table)/sizeof(table[0]))

15、数组和链表的区别?

16、A.c 和B.c两个c文件中使用了两个相同名字的static变量,编译的时候会不会有问题?这两个static变量会保存到哪里(栈还是堆或者其他的)?

static的全局变量,表明这个变量仅在本模块中有意义,不会影响其他模块。他们都放在静态数据区,但是编译器对他们的命名是不同的。如果要使变量在其他模块也有意义的话,需要使用extern关键字。

17、static全局变量与普通的全局变量有什么区别?

  1. 作用域不同

    • 普通全局变量的作用域是整个程序,即可以在程序的任何地方被访问。
    • static 全局变量的作用域仅限于定义它的源文件。其他源文件无法直接访问该 static 全局变量。
  2. 链接属性不同

    • 普通全局变量具有外部链接属性,可以被其他源文件通过 extern 关键字引用。
    • static 全局变量具有内部链接属性,不能被其他源文件引用。
  3. 可见性不同

    • 普通全局变量对整个程序可见。
    • static 全局变量仅在其所在的源文件内可见。

18、static函数与普通函数有什么区别?

  1. 作用域不同

    • 普通函数的作用域是整个程序,在程序的任何地方只要符合函数调用的规则都可以调用。
    • static 函数的作用域仅限于定义它的源文件,其他源文件无法直接调用该 static 函数。
  2. 链接属性不同

    • 普通函数具有外部链接属性,可以被其他源文件通过函数声明和调用。
    • static 函数具有内部链接属性,不能被其他源文件访问和调用。
  3. 减少命名冲突

    • 使用 static 函数可以减少函数名在多个源文件中的冲突可能性,因为它只在本文件内可见。
  4. 封装性

    • static 函数有助于增强源文件内代码的封装性,使得一些只在本文件内使用的功能得以隐藏和隔离。

19、程序的局部变量存在于栈(stack)中,全局变量和静态变量存在于静态数据区 中,动态申请数据存在于堆( heap)中。

20、用两个栈实现一个队列的功能?要求给出算法和思路!

设2个栈为A,B, 一开始均为空.
入队:
        将新元素push入栈A;
出队:
        (1)判断栈B是否为空;
        (2)如果不为空,则将栈A中所有元素依次pop出并push到栈B;
        (3)将栈B的栈顶元素pop出;

21、程序输出结果?

#include <stdio.h>

int sum(int a)
{
    auto int c = 0;
    static int b = 3;
    c+=1;
    b+=2;
    return (a+b+c);
}

int main()
{
    int i;
    int a = 2;
    for(i = 0;i<5;i++)
    {
        printf("%d,",sum(a));
    }
}

输出结果:

22、case 语句之后没有break,所以会执行完所有的条件。

  • 22
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一些可能会在C语言面试中出现的问题: 1. 什么是指针? 指针是一个变量,其值为另一个变量的地址。在C语言中,指针变量用于存储地址,以便可以访问该地址处存储的数据。 2. 如何声明一个指针变量? 指针变量的声明方式如下: ``` int *p; ``` 其中,`int`是指向的数据类型,`*`表示该变量是一个指针变量,`p`是变量名。 3. 如何使用指针访问变量的值? 使用指针访问变量的值需要使用解引用运算符`*`,例如: ``` int a = 10; int *p = &a; printf("%d", *p); // 输出:10 ``` 4. 什么是动态内存分配? 动态内存分配是指在程序运行时根据需要分配内存空间。在C语言中,可以使用`malloc()`函数分配动态内存空间,使用`free()`函数释放已分配的内存空间。 5. 如何使用结构体? 结构体是一种用户自定义的数据类型,可以使用关键字`struct`定义。例如: ``` struct person { char name[20]; int age; }; ``` 可以使用以下方式定义结构体变量: ``` struct person p1; p1.age = 20; strcpy(p1.name, "Tom"); ``` 6. 什么是指针数组? 指针数组是一个数组,其中每个元素都是指针类型。例如: ``` int a = 10, b = 20, c = 30; int *arr[] = {&a, &b, &c}; printf("%d", *arr[0]); // 输出:10 ``` 7. 什么是函数指针? 函数指针是一个指向函数的指针变量。例如: ``` int add(int a, int b) { return a + b; } int (*p)(int, int) = add; printf("%d", (*p)(1, 2)); // 输出:3 ``` 其中,`p`是一个指向函数`add`的指针变量,可以通过`(*p)(1, 2)`调用该函数。 以上是一些常见的C语言面试题,希望能对你有帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值