C++ 指针 部分
基本知识:在内存中的每个字节都有一个编号,这就是“地址”,相当于旅馆中的房间号。记住,内存单元的地址和内存单元的内容是两个不同的概念。
程序在编译之后,就已经将变量名转换成变量地址,对变量值的存取都是通过地址进行的。按照变量地址存取变量值的方式称为“直接存取方式”,或直接访问方式。另一种是“间接存取方式”:将变量i的地址存放在另一个变量中。可以在变量中定义这样的一些变量,专门是用来存放地址的。例如,i_pointer用来存放一个整形变量的地址,编译系统给这个变量分配4个字节(假设是3010到3013字节),通过下面语句将i的起始地址(3000)存放到i_pointer中。-----> i_pointer=&i;
其中&是取地址运算符,&i是变量i的地址。执行此语句后,i_pointer的值就是3000(即变量i所占用的起始地址)。若要取出i的值,可以直接访问,也可以采用间接方式:先找到存放“i的地址”的变量i_pointer。然后从中取出i的地址(3000),然后到3000开始的4个字节中取出i的值(3)。由于通过地址能找到所需的变量单元,所以说,地址指向该变量单元。因此将其形象化的称为“指针”。意思是通过它能访问以它为地址的内存单元。一个变量的地址称为该变量的指针。例如整形变量i的地址是3000,因此3000就是整形变量i的指针。------------------------------------》》指针就是地址,地址也就是指针。
1.变量和指针
变量的指针就是变量的地址。用来存放变量地址的变量是指针变量。指针变量是指向另外一个变量。c++中用“*”符号来表示“指向”,例如i_pointer是一个指针变量,而*i_pointer表示i_pointer所指向的变量。
2.定义指针变量
记住:所有变量在使用前必须定义,也就是指定其类型,这样是为了在编译时可以按照类型分配存储空间。
int *i_pointer,*j_pointer。这里开头的int是指:所定义的指针变量是指向整形数据的指针变量,也就是说这两个变量只能存放整形数据的变量的地址,而不能存放浮点型或其他类型的数据的地址。
注意:
(1)i_pointer,j_pointer是变量名,而*i_pointer,*j_pointer不是变量名,“*”不是指针变量的一部分,在定义变量时在变量名前加上一个“*”表示该变量是指针变量。
(2)不能用一个整数给一个指针变量赋初值,int *i_pointer=2000是错误的。可以将已经定义的变量的地址作为指针变量的初值。int i;int *i_pointer=&i;
(3)在定义指针变量时,必须指定基本类型。因为在“使指针移动1个位置”时或者“使指针值加1”时,在不同的类型中,使地址值增加的字节数是不同的。例如,整形数据,使“指针加1”意味着地址值加4字节,而对于双精度数据,则意味着地址值增加8个字节。
3.引用指针变量
有两个与指针变量有关的运算符:
(1)& 取地址运算符;(2)指针运算符(或称间接访问运算符)
如:&a为变量a的地址,*p为指针变量p所指向的单元。
关于“*”和“&”的一些说明:
一。“&*pointer_1=&a”的含义是什么?“*”和“&”的优先级相同,所以是自左至右的方式结合。因此是先进行*pointer_1的运算,它就是变量a。在执行&运算,即可得到a的地址。
二。”*&a“的含义是什么?先进行&a运算,得到a的地址,在进行*运算,得到a所指向的变量。
4.指针作为函数参数
函数的参数不仅可以是整型,浮点型,字符型等数据,还可以是指针类型。作用是将一个变量的地址传送给被调用的形参。
注意:在调用函数的时候,函数的形参应该有int,如void swap(int *pa,int *pb){ };而调用实参时候,只写变量,不用写类型,如swap(pointer_1,pointer_2)。
void swap(int x,int y)
{int temp;
temp=x;
x=y;
y=temp;
}
通过实参void swap(a,b)调用void swap(int x,int y)来进行值传递。a的值传给了x,b的值传给了y。在执行完调用后,x和y的值换了,但是实参a和b的值并没有换,也就是说由于虚实结合是采用单向的“值传递”方式,只能从实参向形参传递,形参值的改变无法回传给实参。
但是,可以使用指针变量所指向的变量值发生变化,函数调用后,这些变量值的变化依然保留下来了,这样就实现了“通过调用函数使变量的值发生变化,在主调函数中使用这些改变了的值”的目的。
感悟:如果想通过函数调用得到n个要改变的值,可以采用下面的步骤:
1.在主调函数中设n个变量,用n个指针变量指向他们;
2.编写被调函数,其形参为n个指针变量,这些形参指针变量应当与主调函数中的n个指针变量具有相同的基类型;
3.在主调函数中将n个指针变量作实参,将他们的值(是地址)传给所调用函数的n个形参指针变量,这样,形参指针变量也指向这n个变量;
4.通过形参指针变量的指向,改变该n个变量的值;
5.在主调函数中就可以使用这些改变了值的变量。
切记:实参变量和形参变量之间的数据传递是单向的“值传递”方式。指针变量作为函数参数也要遵守这一规则。
当看到类似于这样的一些函数:viod exchange(int *,int *,int *)和void swap(int *,int *)的时候;直接应该很快地判定这是声明基本类型为整型的指针变量。
C++ 指针 部分的更多相关文章
- TODO:Golang指针使用注意事项
TODO:Golang指针使用注意事项 先来看简单的例子1: 输出: 1 1 例子2: 输出: 1 3 例子1是使用值传递,Add方法不会做任何改变:例子2是使用指针传递,会改变地址,从而改变地址. ...
- enote笔记法使用范例(2)——指针(1)智能指针
要知道什么是智能指针,首先了解什么称为 “资源分配即初始化” what RAII:RAII—Resource Acquisition Is Initialization,即“资源分配即初始化” 在&l ...
- C++虚函数和函数指针一起使用
C++虚函数和函数指针一起使用,写起来有点麻烦. 下面贴出一份示例代码,可作参考.(需要支持C++11编译) #include <stdio.h> #include <list> ...
- C++11 shared_ptr 智能指针 的使用,避免内存泄露
多线程程序经常会遇到在某个线程A创建了一个对象,这个对象需要在线程B使用, 在没有shared_ptr时,因为线程A,B结束时间不确定,即在A或B线程先释放这个对象都有可能造成另一个线程崩溃, 所以为 ...
- c 数组与指针的使用注意事项
数组变量和指针变量有一点小小的区别 所以把数组指针赋值给指针变量的时候千万要小心 加入把数组赋值给指针变量,指针变量只会包含数组的地址信息 而对数组的长度一无所知 相当于指针丢失了一部分信息,我们把这 ...
- Marshal.Copy将指针拷贝给数组
lpStatuss是一个UNITSTATUS*的指针类型实例,并包含SensorDust字段 //定义一个数组类型 byte[] SensorDust = new byte[30] //将指针类型拷贝 ...
- C++智能指针
引用计数技术及智能指针的简单实现 基础对象类 class Point { public: Point(int xVal = 0, int yVal = 0) : x(xVal), y(yVal) { ...
- EC笔记:第三部分:17、使用独立的语句将newed对象放入智能指针
一般的智能指针都是通过一个普通指针来初始化,所以很容易写出以下的代码: #include <iostream> using namespace std; int func1(){ //返回 ...
- 智能指针shared_ptr的用法
为了解决C++内存泄漏的问题,C++11引入了智能指针(Smart Pointer). 智能指针的原理是,接受一个申请好的内存地址,构造一个保存在栈上的智能指针对象,当程序退出栈的作用域范围后,由于栈 ...
- 智能指针unique_ptr的用法
unique_ptr是独占型的智能指针,它不允许其他的智能指针共享其内部的指针,不允许通过赋值将一个unique_ptr赋值给另一个unique_ptr,如下面错误用法: std::unique_pt ...
随机推荐
- react 导航切换
<ul class="nav"> <li onClick={() => this.changeFontColor(0)} className={`${0 = ...
- python多进程和多线程编程
17 多线程和多进程并发 The modules described in this chapter provide support for concurrent execution of code. ...
- 洛谷——P2171 Hz吐泡泡
P2171 Hz吐泡泡 题目描述 这天,Hz大大心血来潮,吐了n个不同的泡泡玩(保证没有重复的泡泡).因为他还要写作业,所以他请你帮他把这些泡泡排序成树(左子树<=根<右子树).输出它的后 ...
- Gym - 101670F Shooting Gallery(CTU Open Contest 2017 区间dp)
题目&题意:(有点难读...) 给出一个数字序列,找出一个区间,当删除这个区间中的两个相同的数字后,只保留这两个数字之间的序列,然后继续删除相同的数字,问最多可以实行多少次删除操作. 例如: ...
- Gym - 101550A(Artwork 倒序+并查集)
题目: 思路: 1.对输入数据离线,先把所有的黑线都画出来,统计一下剩余的白色连通块的个数,dfs过程将一个连通块放到一个集合中. 2.倒着往前消去黑线,如果当前的块A是白块就看他的四周有没有白块:有 ...
- C++异常:exception
基本知识 下图表示了标准异常的继承关系 exception是所有标准异常的基类,自定义异常也需要继承exception,如下例: #include "pch.h" #include ...
- hdu 1166敌兵布阵(线段树入门题)
>>点击进入原题测试<< 思路:这两天在学线段树,这个题直接手敲一下线段树就行了,都没有用上懒人标记.入门题 cin,cout会超时,记得加std::ios::sync_wit ...
- chrome浏览器中解决embed标签 loop="true" 背景音乐无法循环的问题。
今天试了下在html网页中加入背景音乐并设置为循环播放.一开始用<embed>标签,设置loop="true", 但是结果发现在IE浏览器可以,但是在chrome浏览器 ...
- nyoj 31 5个数求最值
5个数求最值 时间限制:1000 ms | 内存限制:65535 KB 难度:1 描述 设计一个从5个整数中取最小数和最大数的程序 输入 输入只有一组测试数据,为五个不大于1万的正整数 输 ...
- RDLC报表总结
这2天纠结的报表基本上已近完成大部分功能.现在总结一下自己近期的学习成果 首先制作微软RDLC报表由以下三部分构成:1.制作自己的DateSet集合(就是报表的数据集):2.制作自己的报表文件.rdl ...