文章目录1、指针变量1.1 基本概念1.2 指针运算1.3 面试题2、 常量和常量指针2.1 字面常量和符号常量2.2 const指针常量2.2.1 常量指针2.2.2 常量指针变量2.2.3 指针常量3、总结1、多级指针2、void * 的含义与void **面试 1面试2面试3

1、指针变量

1.1 基本概念

与普通变量不同,指针定义时的数据类型并不是指针变量本身的数据类型,而是其所指目标数据的数据类型,称之为基类型。指针初始化的一般形式如下:

数据类型 * 指针名=初始地址值;

其中指针变量名前的仅仅是一个说明符,表示其后的名称是一个指针变量名。这里的并没有访问指针目标的含义。

有关指针的注意事项如下:

在定义指针变量后系统为该指针变量分配一个地址大小的存储单元,指针变量中存放的是地址值。特别注意,无论指针变量的基类型是何种数据类型,占用的内存大小都是相同的,例如“char *p1;double *p2”,在32位系统中有sizeof(p1)=sizeof(p2)=4,即p1和p2两个指针变量均占用4个字节。

尽管任何指针变量中存放的都是地址值,但一个指针变量只能存放相同基类型的数据地址。

一个指针变量本身占用的空间很小,但可以指向一整块很大的连续控件,这个一整块的连续控件通常是采用动态分配函数malloc分配,存放在堆空间中。

指针和地址有什么区别?指针意味着已经有一个指针变量存在,其值是一个地址,指针变量本身也有地址,而地址本身并不代表任何变量存在,地址仅表示内存空间的一个位置。

1.2 指针运算

指针与整数的加减:p±n 以该地址量为基点的其阿芳或后方的第n个数据的地址。例如,对于基类型为type的指针p,p±n的结果是地址值p±n*sizeof(type),其中sizeof(type)称之为步长,显然步长是与指针变量的基类型有关。

指针++和–:++代表运算后指向下一个数据的位置,指针–代表运算后指向上一个数据的位置,运算后指针地址值的变化量取决于滋镇的基类型。

两个指针相减:并非他们的两个地址值直接做减法运算,而是两指针所指地址之间的数据个数。

NULL(与0等效):一旦某个指针赋值为NULL,就将该指针值设置为0,表示真真变量没有意义,就不能再存储数据,如int *p=NULL, *p=10,是错误的。

也就是说我们一定要记住,指针运算指的是针对指针的基类型进行的运算,而不是地址的加加减减

野指针:一个指针变量的值(地址值)为垃圾值的指针变量称之为野指针;

产生野指针的原因及其解决办法如下:

指针变量定义时没有被初始化,解决办法是在定义指针时初始化,可以是具体的地址值,也可以是NULL。

指针p被free或者delete之后没有置为NULL,后面又去使用。解决办法就是释放指针指向的内存空间,然后将指针指向NULL。

指针操作超越了所指变量的作用域,解决办法是在所指变量的作用域结束之前释放掉变量的纸质空间,并让指针指向NULL。

1.3 面试题

以下程序的输出是()

int *pint=0;

pint+=6;

printf("%d\n",pint);

答案:24

首先题中在定义指针的时候p=0,也就是相当于p=NULL.

其次,+6,其实也就是相当于+6*sizeof(pint);所以输出的地址值是24

以下程序的输出结果是什么?

#include

void main()

{

int*p1,*p2;

int value;

p1=(int *)0x500;

p2=(int *)0x508;

value=p2-p1;

printf("%d\n",value);

}

输出结果是2

解析:8/4=2

以下程序执行会输出什么?

#include

int main()

{

char *p="Linux";

printf("[%c]",*p++);

printf("[%c]",*p);

return 0;

}

请问执行Test函数会有什么样的结果?

#include

#include

#include

void test (void)

{

char *str=(char*)malloc(100);

strcpy(str,"hello");

free(str);

if(str!=NULL)

{

strcpy(str,"world");

printf(str);

}

}

void main()

{

test();

}

因为执行free(str)语句后,str会成为野指针,其中地址值是不为NULL的垃圾地址,将world字符串存放在垃圾地址空间中,后果难以预料,非常危险。

2、 常量和常量指针

2.1 字面常量和符号常量

常量分为字面常量和符号常量。字面常量只能引用不能修改,字面常量通常保存在静态数据区,由p指针指向它,不能通过p指针修改该常量。

char *p="abc";

像上面这种写法,在C语言中是在太多了,只能由p指针指向它,不能通过p指针修改该常量。

其中“abc”为常量,程序员最好采用const char *p="abc"定义。这样在后面执行 *p='x’就会发生错误,也能一眼找到原因。

另外,如果p指向的常量字符串不是通过malloc函数分配的,执行free§,会导致程序崩溃。

使用const定义,const的意思是“一个不能被改变的变量”

注意对于define只是替换语句,不是指令,所以没有;分号,但是,const是指令,所以有;分号。

const常量有数据类型,而宏常量没有数据类型。

可以把const常量的地址赋给指针变量,例如:const int i=10;int *p=&i ;

C中默认这种隐式转换,但是在C++中,“cannot convert from ‘const int *’ to ‘int *’”编译错误,需要采用强制转换,即 int *p=(int *)&i ;

2.2 const指针常量

3类:常量指针、常量指针变量、指针变量

2.2.1 常量指针

在定义指针时用const关键字进行修饰,称为const指针常量。

const char *p

用const修饰 * 时称为常量指针,这样就不能通过该指针变量修改指向的内容。

2.2.2 常量指针变量

在C++中还可以用const修饰指针变量名,称之为常量指针变量。

char *const p;

表示指针p是一个常量指针变量,p的值不能再法神改变,所以必须初始化,一旦初始化,p不能指向其他数据,但可以通过指针p修改所指的内容。

#include

#include

#include

int main()

{

int a=10;

int *p=&a;

int * const q=p;

*q=56;

printf("shuchu %d",*p);

printf("chuchu %d",*q);

}

解释:也就是常量指针变量是在指针的前面加上const,这样,这个指针变量其实也就是初始值代表的指针变量,所以更改这个指针变量的内容,也会导致赋予的指针变量的内容改变。

2.2.3 指针常量

指针变量即为常量指针,又是常量指针变量,例如:

const char * const p;

指针常量,前一个const修饰指针变量的定义,后一个const修饰变量名,指针p必须初始化,并且p的值和指向的内容都不能修改。

#include

#include

#include

int main()

{

int a=10;

int *p=&a;

const int * const q=p;

*q=56;

printf("shuchu %d",*p);

printf("chuchu %d",*q);

}

如上图,编译错误

3、总结

注意,

const int *p=&a;

int const *p=&a;

以上这两个表达式是相同的,都是常量指针,两个const 都是针对*p。

所以值不能改变,而指向地址可以改变。

int * const p ;

const是去修饰 p指针的,所以指针地址不能改变,但是指向的内容值是可以改变的,故称之为常量指针变量。

最后一种

const int * const p

是同时针对地址和值,所以都不能改变。

1、多级指针

在C中指针还可以指向另外的指针,这种指向指针的指针就称之为多级指针。(这一点,只要理解了,指针变量存储了指向的地址,另外指针变量自身也有自己的地址)

int x=10;

int *p=&x;

int **pp=&p;

int ***ppp=&pp;//三级指针

理解:也就是说,**p取p的地址,(注意不是,p指向的地址,如果写成p,那就成了p的指向地址了,所以需要写成 **pp=&p)

2、void * 的含义与void **

void *p;

int *p;

p1=p2;

"无类型”可以包含“有类型”,void *可以指向任何类型的数据。

void ** 可以看做 (void * *)

也就是类型void * 的类型转换。

(void *) 相当于一个转换成一个无类型的地址。

int n=10;

int *p=& n;

printf("%d\n",*(void ** )p);

(void **)p 相当于(int *) (void *p)

也就是说,( void ** )p相当于转换成空指针类型,再强制类型转成p的基类型。

面试 1

int main()

{

char * p="hello ,world";

return 0;

}

上面程序中p和“hello,world”分别存储在内存中的哪个区域?

p指针变量是在栈控件分配的,

它指向的常量字符串“hello,world”是在静态数据区分配的。

面试2

以下程序有什么问题?

#include

#include

#include

void main()

{

int i,*p;

p=(int *)malloc(3*sizeof(int));

for(i=0;i<3;i++)

{

*(p+i)=i+1;

printf("%d\n",*(p+i));

}

p++;

free(p);

}

由于释放程序的时候,free释放的不是分配时候的起始地址,所以会导致程序崩溃。

把p++注释掉即可

面试3

以下程序有什么问题

#include

#include

void main()

{

int i,*p,**pp=&p;

p=(int *)malloc(3*sizeof(int));

for(i=0;i<3;i++)

*(p+i)=i+1;

printf("%d\n",**(++pp));

free(p);

}

对于表达式**(++pp),先执行++pp,是增加pp的地址值,此时pp的地址值加1,会指向一个垃圾地址,应该是让p的地址加1,所以应该是 **++pp

#include

#include t

void main()

{

int i,*p,**pp=&p;

p=(int *)malloc(3*sizeof(int));

for(i=0;i<3;i++)

*(p+i)=i+1;

printf("%d\n",++**pp);

free(p);

}

c语言关于内存笔试,4、C语言面试笔试--内存操作-指针相关推荐

  1. 直击招聘程序员面试笔试C语言深度解析,直击招聘 程序员面试笔试C++语言深度解析(直击招聘) pdf epub mobi txt 下载...

    直击招聘 程序员面试笔试C++语言深度解析(直击招聘) pdf epub mobi txt 下载 图书介绍 ☆☆☆☆☆ 李春葆,李筱驰 著 下载链接在页面底部 发表于2021-05-18 类似图书 点 ...

  2. C语言--基础编程题(各公司面试笔试真题)

    下面我会给大家分享下各公司的面试笔试当中的真题,我挑出来的算是相对比较简单基础的一些题目,也适合基础水平的在学编程小白进行练习,大家现在,也动动脑,动动手,把下面我给出来的这些题目,大家自己动手做做, ...

  3. 我的新书——《PHP程序员面试笔试宝典》

    你好,是我琉忆. 一个文艺的PHP开发工程师. 很荣幸能够在这里带来我的第一本新书--<PHP程序员面试笔试宝典>. 一.创作过程 <PHP程序员面试笔试宝典>是我的第一本书, ...

  4. 【书】《数据库面试笔试宝典系列》简介

    [系列书]<数据库面试笔试宝典>相关内容 本文档说明 本文档主要是给数据库笔试面试系列书籍 < Oracle 数据库笔试面试宝典> . <数据库 程序员 面试笔试宝典&g ...

  5. 4、C语言面试笔试--内存操作-指针

    文章目录 1.指针变量 1.1 基本概念 1.2 指针运算 1.3 面试题 2. 常量和常量指针 2.1 字面常量和符号常量 2.2 const指针常量 2.2.1 常量指针 2.2.2 常量指针变量 ...

  6. 1、C语言面试笔试---变量定义和声明

    文章目录 1.背景 2.变量定义和声明 1.局部变量和全局变量 2.变量的存储类别 3.例题 4.内存泄漏 1.背景 2019秋招马上开始了,今天已经是7月30号了,赶紧刷刷C语言,争取在8月中旬刷完 ...

  7. c语言文件 加载内存吗,把文件中的数据加载到内存进行查找C语言实现.docx

    把文件中的数据加载到内存进行查找C语言实现 #define _CRT_SECURE_NO_WARNINGS#include#include#includechar **pp=NULL;void ini ...

  8. 内存管理模拟程序c语言,C语言 内存管理详解

    本文出自: 伟大的Bill Gates曾经失言: 640K ought to be enough for everybody -Bill Gates 1981. 程序员们经常编写内存管理程序,往往提心 ...

  9. c语言20字节的内存的数据怎么读取_C++编程-内存对齐

    内存对齐可以大大提升内存访问速度,是一种用空间换时间的方法. 1.内存对齐的计算机原理 内存地址对齐,是一种在计算机内存中排列数据(表现为变量的地址).访问数据(表现为CPU读取数据)的一种方式,包含 ...

最新文章

  1. 如何获得更多的自由开发者客户
  2. 【项目实践】从零开始学习Deep SORT+YOLO V3进行多目标跟踪(附注释项目代码)...
  3. 【多标签文本分类】Initializing neural networks for hierarchical multi-label text classification
  4. 发布一个用于WinCE的矢量图控件
  5. spring 配置文件无法加载,junit找不到xml配置文件java.lang.IllegalStateException: Failed to load ApplicationContext...
  6. docker查询mysql 有哪些版本的镜像_CentOS安装Docker环境和mysql镜像的记录
  7. Mongodb 分片与副本集
  8. maven 不能使用 snapshot 的解决方式
  9. H5 通过Ajax方式上传文件,使用FormData进行Ajax请求
  10. 通信工程学什么计算机知识,通信技术需要学习哪些知识
  11. React使用jsbarcode条形码插件
  12. 计算机系统基础书记,【盘点】开学第一周:学风浓 教风严 校风正
  13. 超文本传输协议HTTP
  14. python爬虫token_Python入门:模拟登录(二)或注册之requests处理带token请求
  15. 计算机屏幕关机按钮没有了怎么办,电脑每次关机图标不见了怎么办啊
  16. 强化学习入门这一篇就够了!!!万字长文
  17. 友盟推送小米手机通知栏图标显示问题
  18. android studio运行的时候出现Unable to obtain debug bridge错误的解决办法
  19. Arduino-UNO MPU9250/6500
  20. 豪门赘婿!扮猪吃虎!面试10多家软件测试工程师经验分享!

热门文章

  1. 作为程序员,坚持写博客对我们有什么好处?
  2. Linux内核Thermal框架详解十一、Thermal Governor(1)
  3. Monde Nissin向菲律宾证券交易委员会提交首次公开发行注册申请
  4. 关于编程与数学的名言金句——字字珠玑
  5. Caused by: org.apache.ibatis.ognl.TokenMgrError: Lexical error at line 1, column 43. Encountered: <
  6. Cordova+Vue实现Android APP开发(二)-- 打包运行在真机上和打包运行在本地调试,以及打包时候一些问题的处理
  7. 编程常用字体Consolas、Fira Code、Source Code Pro
  8. 用户行为分析大数据平台之(三)实时数据采集
  9. 如何基于TencentOS tiny,快速打造属于自己的IoT小应用?
  10. python基础之字典的更新复制