指针

c/c++常见面试题一

╄→гoц情女王★ 提交于 2020-01-29 04:04:13
找工作这么多天了,贴一下常见基础题吧,谁找工作了还可以复习下。答案有的是缺少很多,想看全百度之谷歌之... 1.进程与线程的区别:   很长重点写了:一个程序必须有一个进程,一个进程要有一个线程。   进程在运行时有独立的内存单元,而线程则是共享内存单元,所以一个线程死掉这个进程就会死掉,但是一个进程死掉程序无所谓。所以多进程程序比多线程要      稳定。   2.c++函数传递参数的方式:   1.直接传递、引用、指针。   他们的优缺点:   1.按值传递,在传递的时候实参被复制了一份,然后在函数体内使用。如果修改函数体内的拷贝,而实参是没有改变的。   2.引用是别名,所以效率别指针快,也比指针安全。(优先使用引用而不使用指针)   3.按值传递和引用传递在传参过程中,都执行强类型检查,而指针传递的类型比较弱,如果参数被声明为void*基本上没有类型检查,只要是指针编译器就认为是合法的,所以这会造成BUG。   4.指针可以干引用的活,而且还可以传递空指针,特别函数特别应用。但是指针用起来本身就很麻烦,如非需要还是不用。 *3.什么是深拷贝和浅拷贝    深拷贝:拷贝了对象的资源,在新对象中又建立了一个新的字段把资源放进去,如果修改其一,另一个不会改变。    浅拷贝:没有拷贝对象资源,它们共享资源,如果改变其一另一个也会随之改变。 4.面向对象的三个基本特征   1)封装

基于C的文件操作

喜夏-厌秋 提交于 2020-01-29 03:02:30
在ANSI C中,对文件的操作分为两种方式,即流式文件操作和I/O文件操作,下面就分别介绍之。 一、流式文件操作 这种方式的文件操作有一个重要的结构FILE,FILE在头文件stdio.h中定义如下: 1 typedef struct { 2 int level; /* fill/empty level of buffer */ 3 unsigned flags; /* File status flags */ 4 char fd; /* File descriptor */ 5 unsigned char hold; /* Ungetc char if no buffer */ 6 int bsize; /* Buffer size */ 7 unsigned char _FAR *buffer; /* Data transfer buffer */ 8 unsigned char _FAR *curp; /* Current active pointer */ 9 unsigned istemp; /* Temporary file indicator */ 10 short token; /* Used for validity checking */ 11 } FILE; /* This is the FILE object */ FILE这个结构包含了文件操作的基本属性

C:指针基础

夙愿已清 提交于 2020-01-29 01:18:03
内存概述 内存 内存含义: 存储器:计算机的组成中,用来存储程序和数据,辅助CPU进行运算处理的重要部分。 内存:内部存贮器,暂存程序/数据——掉电丢失 SRAM、DRAM、DDR、DDR2、DDR3。 外存:外部存储器,长时间保存程序/数据—掉电不丢ROM、ERRROM、FLASH(NAND、NOR)、硬盘、光盘。 内存是沟通CPU与硬盘的桥梁: 暂存放CPU中的运算数据 暂存与硬盘等外部存储器交换的数据 物理存储器和存储地址空间 有关内存的两个概念:物理存储器和存储地址空间。 物理存储器:实际存在的具体存储器芯片。 主板上装插的内存条 显示卡上的显示RAM芯片 各种适配卡上的RAM芯片和ROM芯片 存储地址空间:对存储器编码的范围。我们在软件上常说的内存是指这一层含义。 编码:对每个物理存储单元(一个字节)分配一个号码 寻址:可以根据分配的号码找到相应的存储单元,完成数据的读写 内存地址 将内存抽象成一个很大的一维字符数组。 编码就是对内存的每一个字节分配一个32位或64位的编号(与32位或者64位处理器相关)。 这个内存编号我们称之为内存地址。 内存中的每一个数据都会分配相应的地址: char:占一个字节分配一个地址 int: 占四个字节分配四个地址 float、struct、函数、数组等 指针基础 指针和指针变量 内存区的每一个字节都有一个编号,这就是“地址”。

C++ 中的四种类型转换

烈酒焚心 提交于 2020-01-29 00:26:42
C++ 中的四种类型转换 static_cast, dynamic_cast, const_cast, reinterpret_cast是c++ 中的四种类型转换 1、const_cast 用于将const变量转为非const 2、static_cast 用于各种隐式转换,比如非const转const,void*转指针等 static_cast能用于多态向上转化,如果向下转能成功但是不安全,结果未知; 进行 上行 转换(把派生类的指针或引用转换成基类表示)是 安全 的; 进行 下行 转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是 不安全 的。 char/ a = 'a'; int b = static_cast<char>(a);//正确,将char型数据转换成int型数据 double *c = new double; void *d = static_cast<void*>(c);//正确,将double指针转换成void指针 int e = 10; const int f = static_cast<const int>(e);//正确,将int型数据转换成const int型数据 const int g = 20; int *h = static_cast<int*>(&g);//编译错误,static_cast不能转换掉g的const属性 3

C语言基础三之指针一

丶灬走出姿态 提交于 2020-01-29 00:18:49
空指针 野指针 万能指针 int *p = NULL; int a =1000; p = &a; void* xx = p; *(int*)p = 1000000; printf("%d \n",*p); const 修饰指针 const int a = 10; int b = 100; //第一种 int *p = &a; p = &b; (V) *p = 1000; (V) //第二种 const int *p = &a; p = &b; (V) *p = 1000; (X) //第三种 int * const p = &a; p = &b; (X) *p = 1000; (V) //第四种 const int * const p = &a; p = &b; (X) *p = 1000; (X) 指针数组 char* arr[] = {"aaaa","bbbb","cccc"}; arr[0]表示"aaaa"的地址值 *(arr[0]+1) 表示“aaaa”中第二个元素的值 []的优先级高 ,是的char* arr[]的本质是 一个数组,数组的元素为指针类型 数组指针 char hello[] = {"hello world"}; char (*pHello)[] = &hello; pHello是一个指针类型,指向的元素为char[] 指针做参数和返回值

指针的指针笔记

流过昼夜 提交于 2020-01-28 20:12:32
指针在Wikipedia 上的定义 在計算機科學中,指標(英語:Pointer),是程式語言中的一類數據類型及其物件或變數,用來表示或儲存一個記憶體位址,這個位址的值直接指向(points to)存在該地址的對象的值。 如何理解 指针 是一个普通的变量或常量,但是它存储的是 另一个 变量或常量的地址; 指针的指针 和指针一样,它所存储的也是另一个变量或常量的地址,只不过那是个 指针变量或指针常量 ; 指针的指针的指针 等同样可以递归理解。 函数的指针 和指针唯一的不同是所存储的是一个函数的入口,正像 数组名指向数组的入口 ; 同样的, 什么的指针 ,就是指向什么; 二维数组 下面是一个定义示例: char a[10][100]; 很明显它定义了十个一维字符数组 a[0][100], a[1][100] ... a[9][100]。 运用一维数组的知识,我们可以很容易理解,a[0], a[1] ... a[9] 是十个指针常量,分别指向每个字符数组的首地址。 它们在内存中是这样的 那么 a 是啥,它指向了 a[0] 所在的存储空间,是指向指针的指针。 结构体指针 我们知道我们可以用 结构名.成员 来引用某个特定结构中的成员。 对于结构体指针,假设 p 是一个指向结构的指针,可以用以下两种方法引用结构中的成员: p->x; /* p -> 结构成员*/ (*p).x; /

遍历线索化二叉树

爷,独闯天下 提交于 2020-01-28 18:30:08
遍历线索化二叉树 常规的线索化方式 采用递归地调用的方式,判定条件是当前指针的左子树是否为空 代码实现: public void midOrder ( ) { if ( this . left != null ) { this . left . midOrder ( ) ; } System . out . println ( this ) ; if ( this . right != null ) { this . right . midOrder ( ) ; } } 对比: 但是对二叉树进行线索化之后,不存在空的左右指针,但是单独设置每一个指针的类型,故而条件修改为指针的类型。 代码实现 我的代码 public void midLIst ( ) { if ( this . getLeftType ( ) != 1 ) { this . getLeft ( ) . midLIst ( ) ; } System . out . print ( this + " " ) ; if ( this . getRightType ( ) != 1 ) { this . getRight ( ) . midLIst ( ) ; } } 问题分析与总结: 出现空指针异常,因为到最后一个节点时,其右指针是没有改变,仍旧为null,并且没有对其值进行修改,故而会出现空指针。 代码修改 public

弱势图解AC自动机

别说谁变了你拦得住时间么 提交于 2020-01-28 17:19:48
本篇文章主要详细介绍$AC$自动机的$fail$指针: 如果有什么不完善的地方,请联系我$qwq$ 前置知识: 1、建议学一下$kmp$算法 2、$Trie$ 导入: AC自动机是用来解决多模板匹配问题的,但是,如果就单纯的把每个模板串拼接在一起,或者单个单个匹配的话,肯定是会超时的,而它的思想是把所有的模式串建立一颗$Trie$,然后用文本串来匹配,那么我们就必须在这颗$Trie$树上进行快速跳转来优化,于是,AC自动机就诞生了 重点:fail指针到底是什么? 我们先来思考一个问题,假如我们按照上面的思想,把每一个模式串建立一颗字典树,那么怎样才能在这个模板串失配后快速跳到下一个有可能成功匹配的字符串来匹配呢?我们举个例子:假设文本串是$bcde$,模式串有两个,分别为$bce$和$cd$,我们为两个模式串建一颗$Trie$,如下图: 我们拿着文本串开始匹配,发现匹配到$2$节点后,就失配了,也就是模式串$bce$失配,那么我们如何快速跳到下一个模式串$cd$来匹配呢?这个时候你可能会说,到$0$节点开始匹配呀,可是这样其实就是重头匹配下一个字符串了,效率并不高,在这里,我们其实可以直接跳到$4$号节点开始匹配,为什么?那是因为我们发现$2$号节点是成功匹配了的,只是不能到$3$号节点去,但是我们发现$2$号节点匹配说明了字符$c$在文本串出现过,那么$c$必定会匹配,所以$0

c语言指针初探

天大地大妈咪最大 提交于 2020-01-28 17:15:52
与c语言指针相关联的三个符号,一个是地址符&,一个是间接符号*,还有一个是在声明指针时用到的*符号。 那么什么是指针呢?指针时存储变量地址的变量,不是整型,它就像int,float一样是指针类型。 p = & i ; //p存储的是变量i在内存中的地址 i = * p ; //*符号加在指针p前,表示取的是这个地址上的变量值 printf ( "%p" , p ) ; //打印指针使用%p 例子:定义一个函数用于交换两个变量的值 # include <stdio.h> void interchange ( int , int ) ; int main ( void ) { int a = 5 ; int b = 3 ; printf ( "交换前a=%d,b=%d.\n" , a , b ) ; interchange ( a , b ) ; printf ( "交换后a=%d,b=%d.\n" , a , b ) ; return 0 ; } void interchange ( int a , int b ) { int temp ; temp = b ; b = a ; a = temp ; } 程序运行的结果 因为函数内的变量是局部变量,只存在于函数内部,函数interchange里的ab虽然交换了,但这里的ab和主函数的ab没有关联,它们在内存中的地址都不一样

【C语言进阶剖析】42、内存操作的经典问题分析(二)

梦想的初衷 提交于 2020-01-28 17:11:54
1 常见内存错误 结构体成员指针未初始化 结构体成员指针未分配足够的内存 内存分配成功,但未初始化 内存操作越界 我们记得定义一个指针的时候要初始化,却容易忘记定义结构体变量时初始化指针成员。指针未分配足够的内存会导致越界操作的问题。内存分配成功,但未初始化,这个可能回造成字符串方面的错误。内存操作越界可能会操作不因该操作的内存,比如字符串没有结尾的 ‘\0’,复制的时候没有发现结尾的 ‘\0’,导致越界了。第四条包括的 2,3 条。 2 找内存错误 下面我们来找找下面的程序中哪里出现了内存错误呢? // 42-1.c # include <stdio.h> # include <malloc.h> void test ( int * p , int size ) { int i = 0 ; for ( i = 0 ; i < size ; i ++ ) { printf ( "%d\n" , p [ i ] ) ; } free ( p ) ; } void func ( unsigned int size ) { int * p = ( int * ) malloc ( size * sizeof ( int ) ) ; int i = 0 ; if ( size % 2 != 0 ) { return ; } for ( i = 0 ; i < size ; i ++ ) {