C语言中的指针以及二级指针代码详解

 更新时间:2018年01月20日 09:25:37   作者:luciferbeing  
这篇文章主要介绍了C语言中的指针以及二级指针代码详解,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下

很多初学者都对C中的指针很迷糊,希望这篇blog能帮助到大家:

1.什么是“指针”:

在执行C程序的时候,由于我们的数据是存储在内存中的。所以对于C程序本身来说,如果想找到相应被调用的数据,就要知道存储该数据的内存地址是多少,换言之,C程序通过已知的内存地址到相应的内存位置存储数据。

这里简单说一下内存管理(对于初学者来说。为了避免专业术语引发的理解问题,下面的叙述尽量避免专业定义:),对于现代计算机系统来说,内存空间分为两个区域,一个是“数据区”,一个是“地址区”,“数据区”存储的是用户数据,比如我们要把一个数字“5”存储到计算机(因为一个单纯的自然数“5”,是没有任何意义的,然后对于计算机来说它需要知道你要把什么定义为“5”,你就不得不定义“x=5")对于计算机而言,这个过程分为以下几个部分:

1.在”栈区(stack)(这个定义实在不能避免,初学者的话就请暂时记住这个名字)“开辟一个空间,用来存放”5“

2.另存存放”5“的内存的地址。

3.将步骤2中的内存地址存在另一个区域(专门用来存放地址的指针区),并记下当前存放步骤2中的内存地址的内存地址(好拗口,这里其实是二级指针的概念)

3.建立一个”索引“将x与步骤3中的内存地址关联,存放在”索引区“(请注意,x和5不是存在一起的,而是有一个“映射表”,并且 指向 x的指针不会直接指向5,而是直接指向x,再通过“映射表”找到x的值‘5',这个概念非常重要,后面例子会讲到利用指针交换两个变量的值,就是基于“x和5不是存在一起的”这个基本概念)。

这里再多说一嘴:为什么要以这种方式存放数据?

内存的存储区就像一池湖水,数据就像池水里面的鱼,如果不用内存寻址的方式,那么当你找某个特定数据的时候,就相当于在一池湖水里找某一条叫做“张三”的鱼一样--你得一条一条捞出来辨认。

如果有内存寻址,就像把一池湖水用渔网分成若干网格,每个网格里面放一两条鱼并且把每个网格都编号(编号和鱼的对应关系假如你用一个小本子记起来),这样当你想找某条叫“张三“的鱼时,你只要打开小本子(指针地址)找相应的网格就可以了。

那么,存储数据的内存地址(有点拗口)或者说是上面例子里面记载编号和鱼的对应关系的小本子就叫指针。

举个实例吧,如下图所示,我们将内存存储空间实体化:假设途中两条平行线夹的空间是内存可以存储数据的空间,途中C的位置存储的是数据,那么P的位置存储的就是指针。

如何定义指针?

int *p;

注意:

1.这里的int,指的是指针p对应的存储区的数据格式,并不是指针p的数据格式。你可以理解为指针的数据格式只有一种。

2.*不仅仅是单纯的运算符,它还是声明符。可以把“*”理解为像“int,float,double”等等这样的格式声明。

3.在使用指针p的时候,经常会用到地址运算符“&”,请注意“&”是运算符,运算操作是取地址,可以把p直接赋上一个地址值:

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

于是 *p 的值就是5了。

上面还可以这么写

int i=5; 
int *p=&i; 

从这两个例子的区别可以看出“*”具有类型声明的作用。

再写一个交换两个变量的值的代码:

#include <stdio.h> 
 
void swap(int *a, int *b) 
{ 
 int temp;//创建一个中间变量用于交换位置。 
 temp = *a; 
 *a = *b; 
 *b = temp; 
} 
 
int main() 
{ 
 int m=10,n=22; 
 swap(&m,&n);//这里对于理解内存管理原则非常重要,正如前面所说,变量m和其值10不是存在一个内存存储区,而是两个,它们通过一个映射表映射起来,所以在这里交换m和n的地址值可以理解为交换了m和n的映射表指向位置。 
 printf("m=%d,n=%d\n",m,n); 
 
 return 1; 
 
 
} 

上面是通过改变两个变量地址的方式交换了变量m,n的值。在这个过程用到了内存地址和内存以及指针的定义,如果没有看懂请回头再仔细研究指针的定义。

二级指针:

如果你熟悉了指针的定义,那么二级指针应该很好理解,所谓的二级指针,就是指针的指针。

具体解释一下:因为任何一个变量值(包括指针地址)最后都是要放入到内存中去的,回到之前举的“池子里的鱼”那个例子,所谓的二级指针就是存放那个写着网格和编号的小本子的位置信息(比如你把这个本子放到某个抽屉里了,那么二级指针记载的内容就是“如何找到这个抽屉”)。

二级指针的定义也很简单粗暴,一个指针变量 *p存放这个指针变量地址的二级指针就是 *(*p),你可以直接简单粗暴地简写为**p(编译器是认这个的)。

其他问题:

1.定义一个指针变量*p,那么p到底是什么?

你可以简单粗暴地把的值p理解为 这个指针变量存储的地址。切记千万不要写成:

int *p=5; 

原因就是我之前说过的,这里再重复一次:*p 只是声明变量p存储的内容是地址。*p并不是一个可以赋值的变量,而是一个”特殊的“ 类型定义+变量。

2.该如何在指针中赋值?

下面说几个合法的赋值:

int *temp = *p;//这是二级指针常用的操作,作用是将指针P的值(指针p的值是地址值,指向的是另外一个地址空间)赋给指针temp指向的值,等价于 int *temp;temp=*p; 
int i=115,j=116,*r=&i,*s=&j;//将i的地址赋给 r</span> 

3.对指针的定义迷糊?

你是不是很奇怪:

int i=5,j=6, *a=&i,*b=&j; 

在这里 *a=&i,*b=j是可以的,但是如果你这么写:

int i=5,j=6,*a,*b; 
*a=&i,*b=j; 

这个时候 *a=&i,*b=j就要报错。

为什么?

原因就是我之前说的:你不可以把在 ”int float这样的格式声明后的“”*“理解成为运算符,而是要理解成为一个像”int“这样的格式声明。”int *a,double * n,float *c“这样的搭配含义是”a/b/c是一个指向int/double/float的指针,诸如 int *a=&i这样的声明实际上是 (int *)a=&i。请一定记住这个特殊情况,这样你就不会再迷糊。

4.谨记*a中的*是取(指针a指向的)值运算,&b是取(b所在的内存的)地址运算。在这里字符a存储的是地址,而b存储的是数据,这里再次声明,一定不要被3中提出的“特殊情况”搞混,那只是一个特例,其他情况不可以那样用。

总结

以上就是本文关于C语言中的指针以及二级指针代码详解的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

相关文章

  • C++ STL入门教程(1) vector向量容器使用方法

    C++ STL入门教程(1) vector向量容器使用方法

    这篇文章主要为大家详细介绍了C++ STL入门教程第一篇,vector向量容器使用方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-08-08
  • c语言简单实现文件 r/w 操作方法

    c语言简单实现文件 r/w 操作方法

    由于在 C 语言中 '\' 一般是转义字符的起始标志,故在路径中需要用两个 '\' 表示路径中目录层次的间隔,也可以使用 '/' 作为路径中的分隔符,本文重点给大家介绍用c语言简单实现文件 r/w 操作方法,感兴趣的朋友一起学习吧
    2021-05-05
  • C/C++实现快速排序算法的思路及原理解析

    C/C++实现快速排序算法的思路及原理解析

    这篇文章主要介绍了C/C++实现快速排序算法的思路及原理解析,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-01-01
  • EasyC++编写头文件

    EasyC++编写头文件

    这篇文章主要介绍了C++编写头文件,在一个C++程序中,只包含两类文件——.cpp文件和.h文件。其中,.cpp文件被称作C++源文件,里面放的都是C++的源代码;而.h文件则被称作C++头文件,里面放的也是C++的源代码,感兴趣的小伙伴一起来看下面文章的详细介绍吧
    2021-12-12
  • 利用Matlab制作环形相册效果详解

    利用Matlab制作环形相册效果详解

    这篇文章主要为大家介绍了如何利用Matlab制作出环形相册的效果,文中的示例代码讲解详细,对我们学习Matlab有一定帮助,需要的可以参考一下
    2022-03-03
  • 详解C++元编程之Parser Combinator

    详解C++元编程之Parser Combinator

    借助C++的constexpr能力,可以轻而易举的构造Parser Combinator,对用户定义的字符串(User defined literal)释放了巨大的潜力。
    2021-05-05
  • C++实现浮点数精确加法

    C++实现浮点数精确加法

    这篇文章主要为大家详细介绍了C++实现浮点数精确加法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-05-05
  • 适合初学者的C语言字符串讲解

    适合初学者的C语言字符串讲解

    字符串主要用于编程,概念说明、函数解释、用法详述见正文,这里补充一点:字符串在存储上类似字符数组,所以它每一位的单个元素都是可以提取的
    2022-04-04
  • C++实现基于时序公平的读写锁详解

    C++实现基于时序公平的读写锁详解

    读写锁与普通的互斥锁的区别在于有两种上锁方式:读锁和写锁,不用的用户对同一个读写锁获取读锁是非互斥的,其他情况则是互斥的,本文小编将给大家详细介绍C++实现基于时序公平的读写锁,需要的朋友可以参考下
    2023-10-10
  • 关于C++友元函数的实现讲解

    关于C++友元函数的实现讲解

    今天小编就为大家分享一篇关于关于C++友元函数的实现讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-12-12

最新评论