c++之指针
一、指针的基本概念
指针的作用:可以通过指针间接访问内存。
- 内存编号是从0开始记录的,一般用十六进制数字表示。
- 可以利用指针变量保存地址。
二、指针变量的定义和使用
指针变量定义语法:数据类型 *变量名
int a = ;
//声明指针变量
int* p;
//指针指向a的地址
p = &a;
//利用*解引用,找到指针指向内存中的数据
cout << *p << endl;
三、指针所占内存空间
在32位操作系统下,无论指针数据类型是什么数据类型,都是占4个字节,而在64位操作系统中占8个字节。
四、空指针和野指针
1.空指针:指针变量指向内存中编号为0的空间。
用途:初始化指针变量。
注意:空指针指向的内存是不能够访问的。
int* p = NULL;
//*p;内存0-255之间的内存编号是系统占用的,不可以访问
2.野指针:指针变量指向非法的内存空间
//在程序中,避免出现野指针
int* p = (int*)0x1100;
五、const修饰指针
const修饰的指针有三种情况:
- const修饰指针--常量指针
- const修饰常量--指针常量
- const修饰指针,又修饰常量
int a = ;
int b = ;
//常量指针,指针指向的值不可以改,指针的指向可以改
//即*p=20是非法的,p=&b是合法的
const int* p = &a;
//指针常量,指针的指向不可以改,指向的值可以改
//即*p2=20是合法的,p2=&b是不合法的
int* const p2 = &a;
//指针指向的值和指向的值都不可更改
//即* p3 = 20是不合法的,p3 = &b是不合法的
const int* const p3 = &a;
六、指针配合数组使用
1.通过指针可以访问到数组中的值
int main() {
int arr[] = { ,,,,, };
//数组名就是数组的首个元素的地址
int* p = arr;
//利用指针访问数组中的第一个元素
//解引用取出4个字节中的数据
cout << *p << endl;
//因为p是一个整型指针,执行p++之后,指针指向的就是下一个元素
p++;
//利用指针访问数组中的第二个元素
cout << *p << endl;
}
2.通过指针来遍历数组
//利用指针遍历数组:
int* p2 = arr;
for (int i = ; i < (sizeof(arr) / sizeof(arr[])); i++) {
cout << *p2 << endl;
p2++;
}
七、指针和函数
主要区别是值传递还是引用传递
1.值传递:改变形参的值不影响传递进来的实参
#include <iostream>
using namespace std; void swap(int num1, int num2) {
cout << "交换之前num1的值:" << num1 << endl;
cout << "交换之前num2的值:" << num2 << endl;
int tmp = num1;
num1 = num2;
num2 = tmp;
cout << "交换之后num1的值:" << num1 << endl;
cout << "交换之后num2的值:" << num2 << endl;
} int main()
{
int a = ;
int b = ;
cout << "实参未传入之前a的值:" << a << endl;
cout << "实参未传入之前b的值:" << b << endl;
swap(a, b);
cout << "实参传入之后a的值:" << a << endl;
cout << "实参传入之后b的值:" << b << endl;
system("pause");
return ;
}
输出:

2.引用传递:改变形参的值会影响到实参的值;
#include <iostream>
using namespace std; void swap(int* num1, int* num2) {
cout << "交换之前num1的值:" << *num1 << endl;
cout << "交换之前num2的值:" << *num2 << endl;
int tmp = *num1;
*num1 = *num2;
*num2 = tmp;
cout << "交换之后num1的值:" << *num1 << endl;
cout << "交换之后num2的值:" << *num2 << endl;
} int main()
{
int a = ;
int b = ;
int* p1 = &a;
int* p2 = &b;
cout << "实参未传入之前a的值:" << a << endl;
cout << "实参未传入之前b的值:" << b << endl;
swap(p1, p2);
cout << "实参传入之后a的值:" << a << endl;
cout << "实参传入之后b的值:" << b << endl;
system("pause");
return ;
}
输出:

八、指针函数和数组
封装一个函数,利用指针对数组进行冒泡排序。
#include <iostream>
using namespace std; void bubbleSort(int* p,int length) {
//如果在这里计算数组的长度,输出为1,因为传入进来的是数组的首地址,里面只存放1个元素
//int len = sizeof(arr) / sizeof(arr[0]);
//cout << len << endl;
//arr是一个指针,指向数组的第一个元素,在数组中用下标访问元素的值时,相当于是将指针指向该元素的内存空间
//我的理解是c++会自己定位到那,并取得值
for (int i = length - ; i >= ; i--) {
for (int j = i - ; j >= ; j--) {
if (p[i] < p[j]){
int tmp = p[i];
p[i] = p[j];
p[j] = tmp;
}
}
}
}
void printArr(int* arr, int length) {
for (int i = ; i < length; i++) {
cout << arr[i] << endl;
}
} int main() {
int arr[] = { ,,,,,, };
//注意要在函数外先计算数组的长度
//如果在函数里面计算,由于数组传进去的是首元素的地址,则长度永远是1
int length = sizeof(arr) / sizeof(arr[]);
bubbleSort(arr, length);
printArr(arr, length); system("pause");
return ;
}
输出:

传入数组是引用传递,因此在里面改变了值会影响到原来数组arr的值,所以最后可以直接对arr进行打印输出。
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 ...
随机推荐
- 【集训Day2】字符串
字符串(string) [问题描述] 给一个字符串T,问在字符串T 中可以包含最多多少个不重叠的字符串S. 字符串中的每个字符为小写或者大写字母. [输入格式] 第一行输入一个字符串S. 第二行输入一 ...
- 高性能消息队列(MQ)Kafka 简单由来介绍(1)
Kafka是由Apache软件基金会开发的一个开源流处理平台,由Scala和Java编写.Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者在网站中的所有动作流数据. 这种动作(网页浏 ...
- 【JavaEE】之MyBatis的ParameterType的使用
在MyBatis的Mapper.xml文件中,参数的表示方法有两种:一种是使用 “#{XXX}” 的方式表示的,另一种是使用 “${XXX}” 的方式表示的.今天来介绍以下这两种方式的不同之处. 1. ...
- Chapter 05—Advanced data management(Part 2)
二. 控制流 statement:一个单独的R语句或者是一个复合的R语句: cond:条件表达式,为TRUE或FALSE: expr:数字或字符表达式: seq:数字或字符串的顺序. 1.循环语句:f ...
- c# 窗体开发1 基本控件的使用
namespace firstly #当前命名空间控件 { public partial class Form1 : Form { public Form1() #第一个窗体 { Initiali ...
- Spring Data JPA 条件查询的关键字
Spring Data JPA 为此提供了一些表达条件查询的关键字,大致如下: And --- 等价于 SQL 中的 and 关键字,比如 findByUsernameAndPassword(Stri ...
- 教你如何关闭IIS服务
由于IIS服务器和Apache的默认端口号都是80端口,有时我们需要关闭IIS服务,下面讲讲关闭IIS服务的方法. 方法如下: 1.services.msc,在里面找到一个“World Wid ...
- 比特宇宙-TCP/IP的诞生
前情回顾: 我是一个explorer的线程 我是一个杀毒软件线程 我是一个IE浏览器线程 比特宇宙创世不久,宇宙中开始出现文明. 文明不断碰撞.融合.进化,逐渐分化为几大派系: 施行Unix体制的帝国 ...
- ThinkPHP5——模型关联(一对多关联)
关联定义 一对多关联的情况也比较常见,使用hasMany方法定义,参数包括: hasMany('关联模型名','外键名','主键名',['模型别名定义']); 例如租客表和宿舍表,一个宿舍有多个租客, ...
- TC297B - 外设头文件解析(以IO为例)
打开例程,目录树下的Includes中包含了各个片上资源对应的头文件,这些头文件定义了相应外设的寄存器地址(寄存器是内置于各个 IP 外设中,是一种用于配置外设功能的存储器,就是一种内存,并且有相对应 ...