快速上手系列-C语言之指针篇(一)

浊酒敬风尘

发布时间:18-06-2108:29

指针的灵活运用使得c语言更加强大,指针是C语言中十分重要的部分,可以说指针是C语言的灵魂。当然指针不是万能的,但没有指针是万万不能的,有些操作没有指针是办不到的,如动态内存分配。鉴于学习指针的必要性,从现在开始介绍指针方面的知识,本篇主要介绍指针相关概念及指针的定义与应用两方面的内容:

指针相关概念

1、指针:

我们使用的计算机内存为8G,系统为了更好地管理我们的内存,就为内存区的每一个字节都分配一个编号(唯一),这就是“地址”。指针的实质就是地址,就是这一个个编号。

2、指针变量:

变量在编译的时候系统要为它分配一个地址,如用另一个变量来存放这个地址,那么这个变量就叫指向变量的指针变量。

如图,变量pointer存储在内存中起始地址2122的位置,值为2000,即存放的地址编号为2000,也就是变量i的起始地址,通常我们称变量pointer为指向变量i的指针变量。同样,变量i在内存中的起始位置为2000,其存放的是地址编号3,而地址编号3又指向另一个变量的起始地址。

指针变量就是用来存放指针(地址)的变量,它的值是另一个变量的地址。在32位平台,所有类型变量的地址都是4字节。

3、指针变量实例:

int *p; //指向整型变量的指针变量,用来存放整型变量的地址int a[5]; int *q = a; //指向数组第0个元素的指针变量分析:int a[5],有五个元素,分别是变量 a[0]、 a[1]、 a[2]、 a[3]、 a[4],且a代表的是第0个元素(变量a[0])的起始地址。而变量a[0]的类型是int,所以int *p =a; 是合法的。char *string = "hello"; //指向字符串的指针变量,string 是一个指针变量,用来存放字符串的首地址,而"hello"返回字符串的首地址int (*foo)(int x, int y); //指向函数的指针变量分析:int (*foo)(int x, int y) 中加粗部分说明foo是一个指针变量,那又是怎样的指针变量呢?再看接下来加粗部分:int (*foo)(int x, int y); 这说明foo是一个指向函数(该函数有两个int类型的形参,且返回int 类型的数据)的指针变量struct student *boy; //指向结构体的指针变量

指针的定义与引用:

(1)指针变量定义的格式:

类型标识符 *变量名; 如:int *point;

注意:在定义int *point;的时候 ,加粗部分的*不是取值符,而是修饰point是一个指针变量,如何确定point指向什么类型的变量呢,需要进行下一步:看非加粗部分,int则表示point指向int类型变量或保存int类型变量的地址。

(2)指针变量的初始化,先来看个实例:

说明:

*表示该变量的类型是一个指针变量,指针变量名是p1而不是*p1;如果在同一行定义多个指针变量应该是:int *p1, *p2;而不是int *p1, p2或者 int* p1, p2;给指针变量初始化有两种方式:在定义时初始化,如int *p_2 = &b;先定义再初始化,如int *p1; p1 = &a;*p1是p1所指向的变量的值;一个指针变量只能指向同一个类型的变量。

(3)对于指针变量的两个运算符“*”与“&”:

& 取地址运算符 //&a就代表a的地址(指的是a所在内存空间的起始地址)* 指针运算符 //*p为p所指向的存储单元的内容

(4)如果有 int buf[4] = {1, 2, 3,4}, *p = buf; 意味着p指向buf数组中第0个元素的起始地址

(5)利用指针引用一维数组的元素:如果我们用一个指针变量指向每一个数组元素的地址,然后对这个指针变量作取值运算,就可以引用一维数组。

例如:int buf[10];用数组名引用的方式为:buf[0],buf[1], buf[2]等;

如:int array[10];int *p = array;则此时p+i和array+i都是数组元素array[i]地址

注意:p+i与&array[i]是等价的,而*(p+i)与array[i]是等价的。

(6)引用数组元素:

下标法:array[i]指针法:*(p+i)或*(array+i)array为数组的首地址是一个常量(如0x00C7),因此不能进行array++ 或者 ++array操作。至于原因,如果把array++拆写成简单的形式:array = array+1;就不难看出我们是不能给一个常量量赋值的。int array[10];int *p = array; 这里p是变量,其值为array数组的首地址,p既然是一个变量,那么可以对p进行++操作。

再来看个例子:int a = 100; int *p = &a;

经过测试:*p++、(*p)++、*(p++); 结果值是一样的。至于原因,看几个例子就明白了例一:*p++

说明:*pointer++,pointer指向buf[0],由于*、++是统一优先级且他们的结合性从右至左,即先执行pointer++,但是对于pointer++来说是先用后加,所以先取pointer所指向的地址空间的值1(buf[0]),再执行pointer++操作,即pointer指向地址后移4字节(因为pointer为int *型,其所指向地址空间存放的是int型数据,所以后移4字节而不是1字节),此时pointer指向buf[1], 即pointer所指向地址空间的值为2(buf[1])。

例二:(*p)++

说明:(*pointer)++,pointer指向buf[0], 由于小括号比++的优先级高,所以先取pointer所指向地址空间的值1(buf[0]),然后将值1进行++(得到2),这里pointer所指向的地址没有改变,只是改变了pointer所指向地址空间的值,所以两次打印pointer所指的地址都是010FFC40,再打印这个空间里的值已经被赋值成2了。

例三:*(p++)

说明:*(pointer++),括号的优先级比*的优先级高,所以先执行pointer++,注意pointer++先使用后++,故先取pointer所指向内存空间的值,此时pointer指向buf[0],取值结果为1。然后对pointer进行++,pointer指向地址变为0093F748,即此时pointer指向buf[1],为了验证这一点(即pointer指向buf[1]),再次打印pointer所指向的地址,发现变为0093F748,最后打印*pointer结果为2(buf[1])。

点到为止,再来一条华丽的分割线

快速上手系列-C语言之指针篇(一)的更多相关文章

  1. 瘋子C语言笔记(指针篇)

    指针篇 1.基本指针变量 (1)定义 int i,j; int *pointer_1,*pointer_2; pointer_1 = &i; pointer_2 = &j; 等价于 i ...

  2. C语言重点——指针篇(一文让你完全搞懂指针)| 从内存理解指针 | 指针完全解析

    有干货.更有故事,微信搜索[编程指北]关注这个不一样的程序员,等你来撩~ 注:这篇文章好好看完一定会让你掌握好指针的本质 C语言最核心的知识就是指针,所以,这一篇的文章主题是「指针与内存模型」 说到指 ...

  3. C\C++语言重点——指针篇 | 为什么指针被誉为 C 语言灵魂?(一文让你完全搞懂指针)

    本篇文章来自小北学长的公众号,仅做学习使用,部分内容做了适当理解性修改和添加了博主的个人经历. 注:这篇文章好好看完一定会让你掌握好指针的本质! 看到标题有没有想到什么? 是的,这一篇的文章主题是「指 ...

  4. iOS开发系列--C语言之指针

    概览 指针是C语言的精髓,但是很多初学者往往对于指针的概念并不深刻,以至于学完之后随着时间的推移越来越模糊,感觉指针难以掌握,本文通过简单的例子试图将指针解释清楚,今天的重点有几个方面: 什么是指针 ...

  5. 使用 mongodb 的 Docker Image 快速上手系列 lab

    Docker 主要的概念 Dockerfile => 用來產生 docker image 用的(介紹) Image => 可以用來產生 docker container Container ...

  6. SpringBoot快速上手系列01:入门

    1.环境准备 1.1.Maven安装配置 Maven项目对象模型(POM),可以通过一小段描述信息来管理项目的构建,报告和文档的项目管理工具软件. 下载Maven可执行文件 cd /usr/local ...

  7. 【Python五篇慢慢弹】快速上手学python

    快速上手学python 作者:白宁超 2016年10月4日19:59:39 摘要:python语言俨然不算新技术,七八年前甚至更早已有很多人研习,只是没有现在流行罢了.之所以当下如此盛行,我想肯定是多 ...

  8. [易学易懂系列|rustlang语言|零基础|快速入门|(21)|智能指针]

    [易学易懂系列|rustlang语言|零基础|快速入门|(21)|智能指针] 实用知识 智能指针 我们今天来讲讲Rust中的智能指针. 什么是指针? 在Rust,指针(普通指针),就是保存内存地址的值 ...

  9. 【opencv入门篇】 10个程序快速上手opencv【下】

    导言:本系列博客目的在于能够在vs快速上手opencv,理论知识涉及较少,大家有兴趣可以查阅其他博客深入了解相关的理论知识,本博客后续也会对图像方向的理论进一步分析,敬请期待:) 上篇传送:http: ...

随机推荐

  1. SVN 问题解决之 Working copy path does not exist in repository

    同事的SVN更新时提示某个特定文件提示 Working copy path does not exist in repository svn更新会被这个错误打断,导致无法完全更新 删掉文件再更新仍然有 ...

  2. 数据库之sqlite

    数据创建数据 CREATE TABLE IF NOT EXISTS ArpAudit (ID INTEGER PRIMARY KEY autoincrement NOT NULL, UserName ...

  3. 自适应高度文本框 react contenteditable

    import React, { Component } from 'react'; import PropTypes from 'prop-types'; const reduceTargetKeys ...

  4. EventBus使用教程

    如图准备工作: 父子(子父)组件触发 EventBus.$emit('sub') EventBus.$on('sub',()=>{ console.log(1111222232211122) } ...

  5. 【Distributed】分布式锁

    一.概述 1.1 分布式解决的核心思路 1.2 分布式锁一般有三种实现方式 二.基于Redis的分布式锁 2.1 使用常用命令 2.2 实现思路 2.3 核心代码 Maven依赖信息 LockRedi ...

  6. MySQL sql_mode 说明(及处理一起 sql_mode 引发的问题)

    1. MySQL莫名变成了 Strict SQL Mode 最近测试组那边反应数据库部分写入失败,app层提示是插入成功,但表里面里面没有产生数据,而两个写入操作的另外一个表有数据.因为 insert ...

  7. EtherNet/IP 协议应用层使用CIP协议&CIP协议中使用的TLS和DTLS(Network Infrastructure for EtherNet/IPTM: Introduction and Considerations)

  8. Spark2 jar存档

    spark.yarn.archive需要手动将spark应用依赖jar上传到hdfs,该属性可以避免每一次运行spark应用时都重复打zip包上传到hdfs. 官网http://spark.apach ...

  9. 2018 CERC 混合博弈

    N堆石子 先手最多拿A个 后手最多拿B个 每次都至少要拿一个 谁先取完谁赢 如果A和B相等直接就是一个bash博弈 如果一个石堆的石子数少于min(A,B) 则是个nim游戏 我们先讨论只有N=1且A ...

  10. mysql基础篇--删除

    语法 truncate table 表名; #清空整个表的数据 delete from 表名 where 筛选条件; #按筛选条件删除数据 /* delete和truncate的区别 delete可以 ...