概述
1、空指针和野指针的区别
空指针:
空指针不指向任何实际的对象或者函数。反过来说,任何对象或者函数的地址都不可能是空指针。
空指针是一个特殊的指针,因为这个指针不指向任何地方。这意味任何一个有效的指针如果和空指针进行相等的比较运算时,结果都是false。
在程序中,得到一个空指针最直接的方法就是运用预定义的NULL,这个值在多个头文件中都有定义。
如果要初始化一个空指针,我们可以这样:
Int *p = NULL;
检验一个指针是否为空指针:
If(ip !=NULL)
野指针:
野指针不是空指针,是一个指向垃圾内存的指针。
形成原因:
(1)指针变量没有被初始化。
任何指针变量被刚创建时不会被自动初始化为NULL指针,它的缺省值是随机的。所以,指针变量在创建的同时应当被初始化,要么将指针设置为NULL,要么让它指向合法的内存。例如:
Char *p = NULL;
Char *string = (char*)malloc(1024)
(2)指针被free或者delete之后,没有设置为NULL,让人误以为这是一个合法指针。
free和delete只是把指针所指向的内存给释放掉,但并没有把指针本身给清理掉。
(3)指针操作超越了变量的作用范围。
由于C/C++中指针有++操作,因而在执行该操作的时候,稍有不慎,就容易指针访问越界,访问了一个不该访问的内存,结果程序崩溃。
2、内存分配
补充:栈为后进先出,堆为先进先出
3、C语言跟内存申请相关的函数主要 alloca、calloc、malloc、free、realloc区别
<1>alloca是向栈申请内存,因此无需释放.
<2>malloc分配的内存是位于堆中的,并且没有初始化内存的内容,因此基本上malloc之后,调用函数memset来初始化这部分的内存空间.
<3>calloc则将初始化这部分的内存,设置为0.
<4>realloc则对malloc申请的内存进行大小的调整.
<5>申请的内存最终需要通过函数free来释放.
4、new/delete和malloc/free区别
(1)属性
New/delete是c++关键字(运算符),malloc/free是库函数。
(2)参数
New/delete申请内存时无需指定内存大小,编译器会根据类型自行计算;malloc/free需要指定分配内存大小。
(3)返回类型
New/delete返回对象类型指针,无需进行类型转换;malloc/free分配成功返回void*,需要强制类型转换。如:
Int *p = new int;
Int *p = new int[10];
Int *p = (int*)malloc(1024) ;
(4)动态对象内存管理
不能够把执行构造函数和析构函数的任务强加于malloc/free。因此,malloc/free不能来完成动态对象的内存管理。
(5)c/c++语言区别
malloc/free在c语言中出现,在c++同样能用,但在c++中最好用new/delete,因为new不仅只是分配了内存,还创建了对象。
注意:如果用free释放“new创建的动态对象”,那么该对象因无法执行析构函数而可能导致程序出错。如果用delete释放“malloc申请的动态内存”,理论上讲程序不会出错,但是该程序的可读性很差。所以new/delete必须配对使用,malloc/free也一样。
5、指针与数据类型的大小
指针变量是用来存放某种类型地址的变量。定义一个整型的指针:int* p,定义了一个指针后,编译器会为指针分配一个地址空间,空间大小是指针的大小,类型定义只是在告诉编译器,这个指针标量存放的是什么类型的地址,并不影响指针的空间分配,就是说char*p,和int*p1,p和p1的空间分配大小是一样的。
在32位机上,所有指针类型变量占用内存字节数都为4;
在64位机上,所有指针类型变量占用内存字节数都为8;
各个类型的变量长度是由编译器来决定的,而当前主流的编译器中一般是32位机器和64位机器。32位机器和64位机器中int、char等数据类型所占字节长度对比:
总而言之,long型和指针类型长度不一样。
注意:8位16位单片机所有字节大小减半。
6、指针和数组的区别
(1)区别:
a.指针保存的是数据的地址;数组是用来保存数据的。
b.指针访问数据需要*(取地址符号),间接访问;数组访问数据通过下标直接访问。
c.指针常用于动态数据结构;数组用于存放固定数目而且类型相同的数据。
(2)什么时候数组等同于指针
函数传递参数的时候;因为数组在作为参数传递的时候,把数组名作为的指针首地址进行传递和调用;
void test (int array[]);
void test (int * array);
上面两种函数声明其实都是一样的
7、c语言运算符优先级
8、指针数组和数组指针
指针数组是数组元素为指针的数组(例如 int *p[3],定义了p[0],p[1],p[2]三个指针),其本质为数组,举个例子:
#include<stdio.h>
int main(void)
{
char **p, i;
char *strings[] ={
"one",
"two",
"three"
};
p=strings; //strings是地址的地址,所以要定义**p
for(i=0; i<3; i++)
printf("%sn", *(p++)); //这里*(p++)是取出存储在数组中的每一个字符串的地址
return 0;
}
数组指针是指向数组的指针。例:int (*p)[10]; p即为指向数组的指针,又称数组指针。
9、break、continue、return区别
break是跳出一层循环,continue是结束一趟循环 ,return才是结束所有层循环!
10、return return 0 return -1区别
return:语句用来结束循环,或返回一个函数的值。
return 0:一般用在主函数结束时,按照程序开发的一般惯例,表示成功完成本函数。
return -1::表示返回一个代数值,一般用在子函数结尾。按照程序开发的一般惯例,表示该函数失败;
10、数组和链表的区别
数组:数据顺序存储,固定大小
链表:数据可以随机存储,大小可动态改变
11、 c++种struct和class的区别
(1)如果不申明访问权限,class的默认权限是private,而struct是public
(2)对于继承,如果也没有明确是public继承还是private继承或者是protected继承,class
默认是private的继承,而struct是public继承。
(3)从抽象上来说,class更像是对象的实现体,而struct更像是数据结构的实现体。
12、引用和指针的区别
13、函数指针的使用场景,好处?
函数指针:把一个函数的指针(地址)作为参数传递给另一个函数,并由另一个函数进行调用。
void basketball()//函数1
{
printf("选择篮球");
}
void football()//函数2
{
printf("选择足球");
}
void selectball(void (* ball)())//函数3
{
printf("选择什么球?");
ball();
}
int main(void)
{
selectball(basketball);
selectball(football);
return 0;
}
回调函数的作用:
(1)回调函数就是由客户自己作主的函数,想添加任何功能都行。
比如高德地图获取导航信息,获取之后可以获取想要的数据,还可以在里面写通讯代码。
(2)保密
把回调函数提供给客服,调用回调函数的函数可以编译成链接库。
13、为什么优先使用组合,而不是继承?
https://www.cnblogs.com/BeyondAnyTime/archive/2012/05/20/2510770.html
https://blog.csdn.net/ONE_PIECE_HMH/article/details/53931365
组合:A是B的一部分
继承:A是B的一种
原因:继承“白箱复用”,暴露基内内部实现细节,破坏封装性,基类发生改变派生类随之发生改变,给派生类带来了不可预测性,而组合是多个对象的组合,内部细节是隐藏的,只提供接口进行调用,而且合成关系有助于保持每个类的单一性(不进行修改)。
14、strncpy和memcpy
(1)char* strncpy (char* dest , const char*src , size_t n)
用于字符串之间的拷贝,当dest的空间需要大于等于n+1(最后一个或者多余的部分全部填充‘ ’),如果dest内存小于n,会导致内存溢出
(2)void* memcpy(void* dest , void* src , size_t n)
不局限于字符串之间的拷贝,拷贝字符串的时,且dest的空间大于等于n,只填充一个‘ ’ ,剩余空间填充不确定
特别注意:在用strncpy拷贝16进制时,一旦遇到0x00,后面全部都为‘ ’ ,因此16进制拷贝时最好用memcpy
最后
以上就是帅气冬瓜为你收集整理的常见的c/c++笔试面试题收集6、指针和数组的区别的全部内容,希望文章能够帮你解决常见的c/c++笔试面试题收集6、指针和数组的区别所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复