常见笔试题目1

1、static有什么用途

  • 在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变。

  • 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。

  • 在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是,这个函数被限制在声明它的模块的本地范围内使用

2、引用和指针有什么区别

3、全局变量和局部变量在内存中是否有区别?区别是什么

https://blog.csdn.net/weixin_36194037/article/details/78871097
答:有区别。
全局变量保存在内存的全局存储区,占用静态的存储单元;局部变量保存在栈中,只有在所在函数被调用时才动态地为变量分配存储单元。

引申:
C语言经过编译之后将内存分为以下五个区域
1.栈:由编译器进行管理,自动分配和释放,存放函数调用过程中的各种参数,局部变量,返回值及函数返回地址。操作方式类似数据结构中的栈。
2.堆:用于程序动态申请分配和释放空间。C语言中的malloc和free,C++中的new和delete均是在堆中进行的。正常情况下,程序员申请的空间在使用结束后应该释放,若程序员没有释放空间,则程序结束时系统自动回收。注意,这里的”堆”并不是数据结构中”堆”。
3.全局(静态)存储区:分为DATA段和BSS段。DATA段(全局初始化区)存放初始化的全局变量和静态变量;BSS段(全局未初始化区)存放未初始化的全局变量和静态变量。程序运行结束时自动释放。其中,BSS段在程序执行之前会被系统自动清零,所以未初始化全局变量和静态变量在程序执行之前已经为0。
4.文字常量区:存放常量字符串。程序结束后由系统释放。
5.程序代码区:存放程序的二进制代码。
显然,C语言中的全局变量和局部变量在内存中是有区别的。C语言中的全局变量包括外部变量和静态变量,均是保存在全局存储区中,占用永久性的存储单元;局部变量即自动变量,保存在栈中,只有在所在函数被调用时才由系统动态在栈中分配临时性的存储单元。

4、线程、进程的区别

根本区别:进程是操作系统资源分配的基本单位,而线程是任务调度和执行的基本单位
在开销方面:每个进程都有独立的代码和数据空间(程序上下文),程序之间的切换会有较大的开销;线程可以看做轻量级的进程,同一类线程共享代码和数据空间,每个线程都有自己独立的运行栈和程序计数器(PC),线程之间切换的开销小。
所处环境:在操作系统中能同时运行多个进程(程序);而在同一个进程(程序)中有多个线程同时执行(通过CPU调度,在每个时间片中只有一个线程执行)
内存分配方面:系统在运行的时候会为每个进程分配不同的内存空间;而对线程而言,除了CPU外,系统不会为线程分配内存(线程所使用的资源来自其所属进程的资源),线程组之间只能共享资源。
包含关系:没有线程的进程可以看做是单线程的,如果一个进程内有多个线程,则执行过程不是一条线的,而是多条线(线程)共同完成的;线程是进程的一部分,所以线程也被称为轻权进程或者轻量级进程。

5、内存泄漏一般是由什么原因导致的

https://blog.csdn.net/summer00072/article/details/80861714
内存泄露(memory lock)是指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况。
内存泄露其实并非指内存再物理上的小时,而是在应用程序分配某段内存后,由于涉及错误,死去了对该内存的控制,因而造成了内存的浪费。
一般常说的内存泄露是指堆内存的泄露,堆是动态分配内存的,并且可以分配使用很大的内存,使用不好会产生内存泄露,使用不好会产生内存泄露。频繁的使用malloc和free会产生内存碎片(类似磁盘碎片)。
一般使用malloc、calloc、realloc、new等函数从堆中分配到一块内存,使用完后,也应该对应的调用free或delete来释放内存块,否则这块内存就不能再次使用,造成内存泄露。
对new或malloc出的指针进行重新赋值,也会导致内存泄露

6、什么函数不能申明为虚函数

什么样的函数不能声明为虚函数?1)不能被继承的函数。2)不能被重写的函数。

1)普通函数

普通函数不属于成员函数,是不能被继承的。普通函数只能被重载,不能被重写,因此声明为虚函数没有意义。因为编译器会在编译时绑定函数。

而多态体现在运行时绑定。通常通过基类指针指向子类对象实现多态。

2)友元函数

友元函数不属于类的成员函数,不能被继承。对于没有继承特性的函数没有虚函数的说法。

3)构造函数

首先说下什么是构造函数,构造函数是用来初始化对象的。假如子类可以继承基类构造函数,那么子类对象的构造将使用基类的构造函数,而基类构造函数并不知道子类的有什么成员,显然是不符合语义的。从另外一个角度来讲,多态是通过基类指针指向子类对象来实现多态的,在对象构造之前并没有对象产生,因此无法使用多态特性,这是矛盾的。因此构造函数不允许继承。

4)内联成员函数

我们需要知道内联函数就是为了在代码中直接展开,减少函数调用花费的代价。也就是说内联函数是在编译时展开的。而虚函数是为了实现多态,是在运行时绑定的。因此显然内联函数和多态的特性相违背。

5)静态成员函数

首先静态成员函数理论是可继承的。但是静态成员函数是编译时确定的,无法动态绑定,不支持多态,因此不能被重写,也就不能被声明为虚函数。
————————————————
版权声明:本文为CSDN博主「Datou_Nie」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/nie19940803/article/details/77427219

7、冒泡排序算法的时间复杂度是什么

8、C++中的什么数据分配在栈或堆中

1,栈: 存放局部变量,函数调用参数,函数返回值,函数返回地址。由系统管理
2,堆: 程序运行时动态申请,new 和 malloc申请的内存就在堆上

9、TCP/IP建立连接的过程,三次握手

10、Internet采用哪种网络协议?该协议的主要层次结构是什么?

应用层 文件传输,电子邮件,文件服务,虚拟终端 TFTP,HTTP,SNMP,FTP,SMTP,DNS,Telnet
表示层 数据格式化,代码转换,数据加密 没有协议
会话层 解除或建立与别的接点的联系 没有协议
传输层 提供端对端的接口 TCP,UDP
网络层 为数据包选择路由 IP,ICMP,RIP,OSPF,BGP,IGMP
数据链路层 传输有地址的帧以及错误检测功能 SLIP,CSLIP,PPP,ARP,RARP,MTU
物理层 以二进制数据形式在物理媒体上传输数据

原文链接:https://blog.csdn.net/xinyu913/article/details/48225253

11、C++中sizeof()的值

12、C++中函数的运行

// (1) 程序1
void GetMemory(char **p, int num)
{
	*p = (char *) malloc(num);
}
void Test(void){
	char *str = NULL;
	GetMemory(&str,100);
	strcpy(str, "hello");
	printf(str);
}

输出:

hello

//(2) 程序2
void Test(void){
	char *str = (char *) malloc(100);
	strcpy(str, "hello");
	free(str);
	if(str != NULL){
		strcpy(str , "world");
		printf(str);
	}
}

输出:

world

//(3) 程序3
char *GetMemory(void)
{
	char p[] = "hello world";
	return p;
}
void Test(void){
	char *str = NULL;
	str = GetMemory();
	printf(str);
}

程序出错

13、头文件中的ifndef/define/endif干什么用

一个大的软件工程里面,可能多个文件同时包含同一个一个头文件,当这些文件编译链接成一个可执行文件时,就会出现大量重定义的错误。在头文件中实用#ifndef/#define/ #endif能避免头文件的重定义。

14、#include<filename.h>和#include “filename.h” 的区别

对于#include <filename.h> ,编译器从标准库路径开始搜索filename.h
对于#include “filename.h” ,编译器从用户的工作路径开始搜索filename.h

15、C++中调用C编译器编译后的函数,为什么要加extern “C”?

答:C++语言支持函数重载,C语言不支持函数重载。函数被C++编译后在库中的名字与C语言的不同。
假设某个函数的原型为: void foo(int x, int y);
该函数被C编译器编译后在库中的名字为_foo,而C++编译器则产生像_foo_int_int之类的名字。
C++提供了C连接交换指定符号extern "C"来解决名字匹配问题。
c++语言为了支持重载,对编译时函数的重命名规则进行更改,使用extern “C” 的方式在c++程序中声明c语言文件中的函数,可以在编译时,告诉编译器使用C语言的规则对该函数的的函数名的进行重命名,这样在链接的时候,就可以顺利在.c文件中找到该函数;

16、编写strcat函数

头文件:#include <string.h>

strcat() 函数用来连接字符串,其原型为:
char *strcat(char *dest, const char *src);

【参数】dest 为目的字符串指针,src 为源字符串指针。

strcat() 会将参数 src 字符串复制到参数 dest 所指的字符串尾部;dest 最后的结束字符 NULL 会被覆盖掉,并在连接后的字符串的尾部再增加一个 NULL。

注意:dest 与 src 所指的内存空间不能重叠,且 dest 要有足够的空间来容纳要复制的字符串。

【返回值】返回dest 字符串起始地址。
strcat函数是用来连接字符串的
char *struct(char *strDest, const char *strSrc)

#include <assert.h>

char* my_strcat(char*dest, const char* src)
{
	//1. 找目标空间中的'\0'
	char *ret = dest;   
	//定义指针变量存储目标字符的地址方便最后返回
	assert(dest != NULL);
	assert(src != NULL);
	while(*dest != '\0')	//找'\0'
	{
		dest++;
	}
	//2. 数据拷贝(即strcpy函数的实现)
	while(*dest = *src)
	{
		dest++;
		src++;
	}
	return ret;
}

int main()
{
	char arr[20] = "hello ";

	my_strcat(arr, "world");
	printf("%s\n", arr);

	system("pause");
	return 0;
}

©️2020 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值