一 指针变量的定义

*是用来修饰指针变量的,通常情况下我们定义的手法都是“类型名”+“*”+“指针变量名称”。

有一种简单无脑的“替换法”,作用是防止小括号遗漏而导致定义出现歧义和偏颇。

方法如下:

*修饰指针变量p,那么我们需要指向谁,就先定义谁,然后用小括号+指针变量替换它。

example:

指向整型变量:

int a=100;//定义变量。

int (*p)=&a;//(*p)替换了取代目标a并存入了a的首地址,这也称为指针变量的初始化。

int *p=&a;//判断可以去掉小括号。

同理可得,若我要指向一个数组

int arr[5];

int (*p)[5];//这里判断出来不可去掉小括号,因为*的优先级低于[],这里也是一个很经典的难点,“指针数组”和“数组指针”。

p=arr;//其实和p=&arr[0]一个意思。

int *p[5];//这就是指针数组,指针这个特殊的变量以数组形式出现。

int (*p)[5];//这就是数组指针,它只有一个指针,它的作用是存储数组类型的首地址的。

继续,同理可得

指向函数:int fun(int int); int (*p)(int int);//不该去掉小括号。 p=&fun;

指向结构体:struct stu {} Mystruct; struct stu *p; p=&Mystruct;

指向指针:int *p;int *(*q);int **q;q=&p;

二 指针变量的合法初始化

指针变量如果没有初始化就立即使用的话,不让指针指向一个合法的地址(或者是有操作权限的地址),就会出现段错误。

如果没有指向合法的地址,建议初始化为NULL。

int *p=NULL;//这里有一个易错点,这里应该看作int *p;p=NULL;而不是*p=NULL。

注意,这只是缓兵之计,不要操作指向NIULL的指针。

三 指针变量的类型

判断方法:在指针定义的语句中,把指针名称忽略,剩下的部分就是指针变量的类型。

比如int *p,该指针(p)的类型名是int *,而(*p)的类型则是int。

这个的作用是对赋值语句的判断。

判断了指针变量的类型,我们如何判断该指针类型指向的类型呢?

这个也挺有意思,就是在判断指针变量类型的基础上把 * 去掉就可以了。

例:int *p,该指针(p)的类型名是int *,指向的类型呢就是int。  

以此类推,多推多懂,都是些换汤不换药的玩意。

指针变量指向的类型,决定了取值的宽度。

这个很重要!

因为一个指针既然要选择存储地址,并对其内容进行操作,仅仅是“能知道地址”是远远不够的,我们还需要告诉指针“应该存储多少地址”,只有存储了一个完整的地址,指针才能正常的通过操作地址去操纵其内容。

example:

如果你面对一个4字节的int数据,但是你的指针只能存储2个字节的地址,你以为你还能操作内容吗?你不能啦。

同理,同样都是+1,但是不同的指针变量跳过的字节数目不同,这也是指针变量所指向的类型名的作用。

若我想取出0x0102的值

short *p=(short)#//c++对于格式的要求相当严格,所以必须做一个强制类型转换。

cout<<hex<<*(p+1)<<;//输出结果是102,首位0消除了。

若我想取出0x0203的值

char *p=(char)&num;

cout<<hex<<(short)*(p+1)<<;//原理是先用char越过第一个地址,然后通过强制类型转换为short拿下后两位地址。

取出0x02的值

char *p=(char)&num;

cout<<hex<<(int)*(p+2)<<;//为什么要转换为int类型呢?因为char类型有一点特殊,如果你不进行数值转换的话就会变成输出了一个ASCII值,甚至是乱码都有可能。

四 指针变量的注意事项

void不能开辟空间,所以不能定义普通变量,但是却可以定义指针变量

void num;//不行,无法开辟变量空间

void *p;//彳亍,p自身类型为void *,在平台上为任意类型的指针,32位平台上4B,64位平台上8B。

而且此时的p作为无能的一级指针变量,其本身可以保存任意一级指针的地址编号。

万能指针一般用于函数的形参,以此来达到算法操作多种数据类型的目的。

不要直接对void *的指针变量取 * ,需要取值的话必须临时强转类型,因为void无法判断取多少字节的地址,就会造成地址没取够或者越界访问非法内存的情况出现。

在使用中,“[ ]”就是* ()的缩写。

五 指向同一数组的两个指针变量的关系

两指针变量相减,等于它们之间的元素个数。

两指针变量赋值,使它们指向同一元素。

两指针变量的相等判断,它们是否指向同一处。

两指针变量不能相加,会导致数组越界,是无意义的。

字符串与指针

字符串数组储存的字符串,存储空间在栈区/全局区。而存储在指针变量的字符串,内容存储在文字常量区里,而首地址存储在指针变量里(字符串内容太大了,指针变量放不下)。

七 指针数组

本质是数组,只不过数组的每个元素都是指针。

int *arr[3];  char ch[8];   short str[4];

sizeof(arr)==3*8,  sizeof(ch)==8*8,   sizeof(str)==4*8;

可以把指针组为数组一般去使用。

int num1=1,num2=2,num3=3;

arr[0]=&num1,arr[1]=&num2,arr[2]=&num3;

在字符串数组里面,若想要输出一个完整的字符串的话只需要使用 [ ] 就可以了,但是如果在此基础上在加上 * 的话,就会导致只取出了那个字符串里的首地址的字母。详情如下:

char ch[8];  char arr="China";

ch[0]=&arr;

cout<<ch[0]<<;//输出China。

cout<<*(ch+4)<<;//输出a。

八 数组指针

数组首元素地址和数组首地址:&arr[0]=arr,arr+1跳过一个元素。  &arr,&arr+1跳过整个数组。

数组指针,本质是指针变量,保存数组的首地址:

int arr[5]={1,2,3,4,5};

int *p[5]=NULL;

对数组首地址取* == 数组首元素的地址。

数组指针的本质是指针变量,只不过变量存储的是数组的首地址。

Tips:

1.32位平台的任何指针变量都是4字节,64位平台的任何指针变量都是8字节;

2.“段错误”指的是在程序运行过程中出现了错误;

3.NULL空的本质是(void *)0,是内存中的起始位置;

4.在使用指针的过程中,&和*相遇了,从右往左依次抵消;

5.指针在读取地址的过程中,是从低地址向高地址读取的,但存入地址时却是高地址向低地址存入的;

6.一个指针变量定义的成不成功,主要在于能不能为这个变量开辟空间;

7.指针未初始化不要取 * ,指针初始化为NULL也不要取 * ,除了void *之外其他类型的指针变量的类型和访问地址的对象类型一定要相互匹配,不然容易造成越界访问的情况;

8.数组名等同于数组元素的第0个元素的地址(首地址),所以可以直接赋值给指针变量;

9.“ [ ] ”是() *的缩写,表示一个指针变量和一个取值符号 * ,[ ]右边的值,表示该数值+在右边,[ ]左边的值,表示该数值+在左边;

10.双引号有两个作用,一个是描述里面的内容为字符串,另一个是取这个字符串的首元素的地址;

c++学习6 指针变量的更多相关文章

  1. c语言学习之基础知识点介绍(十):内存空间模型、地址解释及指针变量

    一.内存 /* 内存: 存在内存里的. 内存分了N多个小空间,每个小空间1个字节 每个小空间有它自己的地址.每个地址之间差1 int类型占用4个字节,等于占了4个空间(有4个地址),不需要记住4个地址 ...

  2. 大一C语言学习笔记(9)---指针篇--从”内存的使用“和“流程控制”的角度来理解“指针变量的使用‘

    #深入理解指针变量 举个错误栗子: //以下代码的目的是输出100和1000,但输出结果只有一个100 #include<stdio.h> #include<malloc.h> ...

  3. 大一C语言学习笔记(7)---指针篇--什么是指针?什么是指针变量?取地址符“&”的作用是什么?地址运算符“*”的作用是什么,怎么理解两者?

    "指针是C语言的灵魂"这句话一开始我没怎么明白,现在接触了指针,终于知道为什么这么说了,因为....难,真难:下面说一下我对这句话的见解: C语言拥有着其他语言所没有的特性---直 ...

  4. (转) 学习C++ -> 指针初步

    学习C++ -> 指针初步 一.指针    1. 什么是指针?        我们知道, 计算机的内存是由一个个独立的存储单元组成, 并且系统会对每一个存储单元分配一个唯一的号码, 称为这个存储 ...

  5. C++学习之指针的常见错误

    C++学习之指针的常见错误       我们在编程的过程中,有时候在使用指针的时候,删除一个指针以后一定要将这个指针设置为空指针,这是因为删除这个指针只是删除这个指针指向的地址,这个指针还真是的存在程 ...

  6. C语言指针篇(一)指针与指针变量

    指针 1. 什么是指针?    2. 指针可不可怕? 3. 指针好不好玩? 4. 怎么学好指针?     C语言是跟内存打交道的语言,指针就是内存地址.指针无处不在,指针并不可怕,相反,等你学到一定程 ...

  7. LR静态存储/动态存储/指针变量脚本说明

    在一次教程学习中,看到该知识点并记录了下来,希望与大家共同探讨学习. 一.静态存储与动态存储 静态存储变量通常是在变量定义时就分定存储单元并一直保持不变, 直至整个程序结束.动态存储变量是在程序执行过 ...

  8. c语言学习笔记 - 指针和字符串

    前面学习了字符串是一种字符数组,又知道了指针变量和数组的关系,这里来看一下指针和字符串的关系. #include <stdio.h> int main(void){ char str = ...

  9. 【C++】初次学习C++指针时的一些易混或疑惑的地方

    C++中的指针是一个比较复杂的知识概念,最近我有在学习这一方面的知识,就借此文章记录一下在学习时容易产生的混淆.本人初次发技术类的分享,可能会有纰漏,欢迎诸位指正^_^! 1.*在两种语境下的含义 先 ...

  10. 我的c++学习(9)指针

    ◆ 1.指针变量的赋值.初始化与简单应用 ,y; y=; // y可以理解成该存储单元的当前名字 int *ip; // ip是一个指针(变量) ip=&y; // ip是存储空间y的地址 c ...

随机推荐

  1. Postman配置多环境请求地址

    在使用Postman测试接口时,一个项目往往有多个环境(测试.正式等),请求不同环境的接口一般只是IP和端口不一样. 这时候我们可以定义多个环境变量,在接口地址中进行引用. 一.添加环境变量 1.点击 ...

  2. (0617 ) centos7运行脚本提示: 没有那个文件或目录 :No such file or directory

    https://blog.csdn.net/hehuihh/article/details/88174007 之前也 遇到: https://www.cnblogs.com/fancy2333/p/1 ...

  3. Linux环境下给python项目写个启停服务

    写个服务,写完后放在/lib/systemd/system路径下 update_rule.server [Unit] Description = TinyScan update rule [Servi ...

  4. Katalon-获取文本内容和预期文本对比(get Test)

  5. 36.201——LTE物理层——总体描述物理层综述协议

    主要包括物理层在协议结构中的位置和功能,包括物理层4个规范36.211.36.212.36.213.36.214的主要内容和相互关系等 The radio interface is composed ...

  6. Android 6.0动态添加权限(Finn_ZengYuan博客)

    1,随着手机版本变高,各种权限也有所限制:以下代码可人性化添加动态权限: 权限工具类1,2,3,4: 1,FinnPermissionConfig.CLass package com.finn.too ...

  7. 【git】3.2git分支-分支的新建与合并

    资料来源 (1) https://git-scm.com/book/zh/v2/Git-%E5%88%86%E6%94%AF-%E5%88%86%E6%94%AF%E7%9A%84%E6%96%B0% ...

  8. 攻防世界-Web_php_include(data协议)

    一道简单的文件包含题目 分析代码可知php://被ban了 此题可以用data://协议 payload为(以下两者皆可使用) ?page=data://text/plain,<?php%20s ...

  9. 从零搭建hadoop集群之安装虚拟机

    1.  打开 VMware 2. 点击编辑 ->  虚拟网络编辑器 点击VMnet8 选中NAT模式(于虚拟机共享主机的ip地址) 设置子网IP 点击NAT设置 3.   设置网关 :和子网IP ...

  10. C盘满了

      今天电脑提示说C盘磁盘满了,于是开始做磁盘清理 右击C盘,点管理. 点击磁盘清理,勾选中临时文件.下载.回收站.缩略图,然后点击清理系统文件. 再去查看C盘仍然没有多大变化,于是挨个翻看C盘到底哪 ...