指针

通过一段简单的程序,引入指针的概念

#include <iostream>
using namespace std; // changeValue函数的定义
void changeValue(int n)
{
n = 10;
} // 程序入口main
int main(int argc, char *argv[])
{
int num = 1; changeValue(num); cout << num << endl; // 这里输出num = 1 return 0;
}

程序执行第一行:定义了一个int类型的变量num,由于变量num是int类型,在内存中给变量num分配4个字节的存储空间。

程序执行第二行:调用函数changeValue,此时该函数被加载进内存,函数changeValue压栈,形参声明了int类型的变量n,内存会给变量n分配4个字节的存储空间。调用changeValue传入是num变量,等价于将num存储空间的值赋值给了变量n。

程序执行changeValue函数体:将变量n存储空间赋值了10。

此时的内存图如下:



程序执行输出num等价于以十进制打印内存中的变量num的存储空间的value。所以数据的结果是1。

如果想在changeValue内部修改num的值,这时候指针上场了。

指针是什么?

指针也是一种数据类型,指针变量就是保存指向变量内存的地址。通过指针可以修改所指向存储空间的值。

定义一个指针类型变量,修改指向存储空间的值。

要指向变量的类型 *指针变量名;
int *p; // 定义了一个指针变量p 将来指针变量p只能保存int类型变量的内存地址。
int num = 2;
p = &num; // 将int类型变量的num地址赋值给指针变量p
*p = 10; // *p访问保存地址对应的内存空间,也可以说访问指针变量p所指向的存储空间

了解了指针的本质之后对上面的程序进行修改

#include <iostream>
using namespace std; void changeValue(int *n)
{
*n = 10;
} int main(int argc, char *argv[])
{
int num = 1; changeValue(&num); cout << num << endl; // 这里输出num = 10 return 0;
}

此时的changeValue函数形参是一个指向int类型指针变量。可见如果想调用changeValue需要传入int类型的变量的地址值。形参指针变量保存的是变量num的地址值,通过*n可以访问所指向变量num的存储空间的value。

多级指针

开发中最多可能遇到的就是二级指针。根据上面介绍的指针本质我们可以推导出多级指针的使用

int num = 10;
int *p;
p = &num;
*p = 10 int* *pp;// 定义一个int *类型的指针变量pp,pp将来存储的是int *类型变量的地址
pp = &p; // 将int *变量p的地址赋值给变量pp
**pp = 20; // **pp等价于*(*pp) ,*pp访问的是所指向变量p的存储空间也就是变量num的内存地址。其实*pp等价于p,所以**pp等于*p, 最终访问的也是变量num的存储空间。 int** *ppp;
ppp = &pp;
***ppp = 50;

多级指针的技巧:

通过上图多级指针可以根据有多少个箭头层级就通过多个*来访问最终指向的存储空间。

二级指针使用场景

我们清楚通过指针我们修改说指向存储空间的数据。如果想在函数内部修改指针(修改指针的地址值)就需要函数的形参是指针的指针了。

通过下面的代码,分析函数形参传递指针与指针的指针的区别

#include <iostream>
using namespace std; void changePointer(int *p)
{
*p = 10;
} void changePointer(int **pp)
{
// 通过*pp等价于p
*pp = (int *)malloc(100);
} int main()
{
int *buf = NULL; // 通过传递一级指针 在函数内部修改指针指向的空间数据
changePointer(buf); // 通过指针的指针 在函数内部修改指针(修改指针保存的指向内存地址)
changePointer(&buf); return 0;
}

上面的内存 可以通过下图来体现

补充:对于上面的指向指针p的指针pp,int **pp = &p, *pp就等于p。 如果一个指针变量为NULL,控制台输出的地址为0x0。

C开发系列-指针的更多相关文章

  1. iOS开发系列文章(持续更新……)

    iOS开发系列的文章,内容循序渐进,包含C语言.ObjC.iOS开发以及日后要写的游戏开发和Swift编程几部分内容.文章会持续更新,希望大家多多关注,如果文章对你有帮助请点赞支持,多谢! 为了方便大 ...

  2. iOS开发系列--Swift进阶

    概述 上一篇文章<iOS开发系列--Swift语言>中对Swift的语法特点以及它和C.ObjC等其他语言的用法区别进行了介绍.当然,这只是Swift的入门基础,但是仅仅了解这些对于使用S ...

  3. iOS开发系列--并行开发其实很容易

    --多线程开发 概览 大家都知道,在开发过程中应该尽可能减少用户等待时间,让程序尽可能快的完成运算.可是无论是哪种语言开发的程序最终往往转换成汇编语言进而解释成机器码来执行.但是机器码是按顺序执行的, ...

  4. 【Qt编程】基于Qt的词典开发系列<四>--无边框窗口的缩放与拖动

    在现在,绝大多数软件都向着简洁,时尚发展.就拿有道的单词本和我做的单词本来说,绝大多数用户肯定喜欢我所做的单词本(就单单界面,关于颜色搭配和布局问题,大家就不要在意了). 有道的单词本: 我所做的单词 ...

  5. 公共语言运行库(CLR)开发系列课程(1):Pinvoke 简介 学习笔记

    前言 让拖管代码对象和非托管对象协同工作的过程称为互用性(Interoperability),通常简称为 Interop. P/Invoke在托管代码与非托管代码交互式时产生一个事务(Transiti ...

  6. openresty开发系列23--lua面向对象

    openresty开发系列23--lua面向对象 面向对象编程(Object Oriented Programming,OOP)是一种非常流行的计算机编程架构.java,c++,.net等都支持面向对 ...

  7. openresty开发系列15--lua基础语法4表table和运算符

    openresty开发系列15--lua基础语法4表table和运算符 lua中的表table 一)table (表)Table 类型实现了一种抽象的"关联数组".即可用作数组,也 ...

  8. iOS开发系列--Swift语言

    概述 Swift是苹果2014年推出的全新的编程语言,它继承了C语言.ObjC的特性,且克服了C语言的兼容性问题.Swift发展过程中不仅保留了ObjC很多语法特性,它也借鉴了多种现代化语言的特点,在 ...

  9. 【微信小程序开发•系列文章六】生命周期和路由

    这篇文章理论的知识比较多一些,都是个人观点,描述有失妥当的地方希望读者指出. [微信小程序开发•系列文章一]入门 [微信小程序开发•系列文章二]视图层 [微信小程序开发•系列文章三]数据层 [微信小程 ...

随机推荐

  1. 深度探索C++对象模型之第一章:关于对象之C++对象模型

    一.C和C++对比: C语言的Point3d: 数据成员定义在结构体之内,存在一组各个以功能为导向的函数中,共同处理外部的数据. typedef struct point3d { float x; f ...

  2. Bootstrap 附加导航(Affix)插件

    附加导航(Affix)插件允许指定 <div> 固定在页面的某个位置.一个常见的例子是社交图标.它们将在某个位置开始,但当页面点击某个标记,该 <div> 会锁定在某个位置,不 ...

  3. Windows netstat

    { 显示协议统计信息和当前 TCP/IP 网络连接. NETSTAT [-a] [-b] [-e] [-f] [-n] [-o] [-p proto] [-r] [-s] [-x] [-t] [int ...

  4. 期望dp+高斯消元——bzoj3143

    比较经典的题,题解看网上的..https://www.cnblogs.com/GXZlegend/p/7054536.html 自己sort弄错了..还以为是高斯消元写歪了.. #include< ...

  5. js 定位到某个锚点的方法

    html页面内可以设置锚点,锚点定义 Html代码  ? 1 <a name="firstAnchor">&nsbp;</a> 锚点使用 Html代 ...

  6. char类型在传参时接收不到数据的原因

    mybatis的原因!!!!! 数据库这个样子 在postman中调用接口:SQL select * from T_TRAIN_MARSHALLING where TRAIN_NUM is null ...

  7. 《DSP using MATLAB》Problem 8.34

    今天下了小雨,空气中泛起潮湿的味道,阴冷的感觉袭来,心情受到小小影响. 代码: hp2lpfre子函数 function [wpLP, wsLP, alpha] = hp2lpfre(wphp, ws ...

  8. java中一个类不想被继承怎么办?

    方法一:把类声明为final 方法二:对类中的构造器声明为private,类中提供一个static方法,完成对类的初始化.如下代码: public class Base{ private Base() ...

  9. <Django>socket简单实现django简化版

    服务端(自己实现django) ''' django简化版:socket服务端 a.收发浏览器信息----wsgiref.py b.根据用户访问的不同路径执行不同函数 c.从html读取出内容,并完成 ...

  10. POJ - 2774~POJ - 3415 后缀数组求解公共字串问题

    POJ - 2774: 题意: 求解A,B串的最长公共字串 (摘自罗穗骞的国家集训队论文): 算法分析: 字符串的任何一个子串都是这个字符串的某个后缀的前缀. 求 A 和 B 的最长 公共子串等价于求 ...