一、指针的基本概念

指针的作用:可以通过指针间接访问内存。

  • 内存编号是从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++之指针的更多相关文章

  1. TODO:Golang指针使用注意事项

    TODO:Golang指针使用注意事项 先来看简单的例子1: 输出: 1 1 例子2: 输出: 1 3 例子1是使用值传递,Add方法不会做任何改变:例子2是使用指针传递,会改变地址,从而改变地址. ...

  2. enote笔记法使用范例(2)——指针(1)智能指针

    要知道什么是智能指针,首先了解什么称为 “资源分配即初始化” what RAII:RAII—Resource Acquisition Is Initialization,即“资源分配即初始化” 在&l ...

  3. C++虚函数和函数指针一起使用

    C++虚函数和函数指针一起使用,写起来有点麻烦. 下面贴出一份示例代码,可作参考.(需要支持C++11编译) #include <stdio.h> #include <list> ...

  4. C++11 shared_ptr 智能指针 的使用,避免内存泄露

    多线程程序经常会遇到在某个线程A创建了一个对象,这个对象需要在线程B使用, 在没有shared_ptr时,因为线程A,B结束时间不确定,即在A或B线程先释放这个对象都有可能造成另一个线程崩溃, 所以为 ...

  5. c 数组与指针的使用注意事项

    数组变量和指针变量有一点小小的区别 所以把数组指针赋值给指针变量的时候千万要小心 加入把数组赋值给指针变量,指针变量只会包含数组的地址信息 而对数组的长度一无所知 相当于指针丢失了一部分信息,我们把这 ...

  6. Marshal.Copy将指针拷贝给数组

    lpStatuss是一个UNITSTATUS*的指针类型实例,并包含SensorDust字段 //定义一个数组类型 byte[] SensorDust = new byte[30] //将指针类型拷贝 ...

  7. C++智能指针

    引用计数技术及智能指针的简单实现 基础对象类 class Point { public: Point(int xVal = 0, int yVal = 0) : x(xVal), y(yVal) { ...

  8. EC笔记:第三部分:17、使用独立的语句将newed对象放入智能指针

    一般的智能指针都是通过一个普通指针来初始化,所以很容易写出以下的代码: #include <iostream> using namespace std; int func1(){ //返回 ...

  9. 智能指针shared_ptr的用法

    为了解决C++内存泄漏的问题,C++11引入了智能指针(Smart Pointer). 智能指针的原理是,接受一个申请好的内存地址,构造一个保存在栈上的智能指针对象,当程序退出栈的作用域范围后,由于栈 ...

  10. 智能指针unique_ptr的用法

    unique_ptr是独占型的智能指针,它不允许其他的智能指针共享其内部的指针,不允许通过赋值将一个unique_ptr赋值给另一个unique_ptr,如下面错误用法: std::unique_pt ...

随机推荐

  1. 将py文件打包为exe文件方法

    前提: pip是依赖python的,首先检查下windows机器上有没有安装python,或者有没有添加到环境变量中,如果都没有需要安装或者加入环境变量 安装pip 下载地址: https://pyp ...

  2. 01-python中一切皆对象

    python一切皆对象 Python中一切皆对象,在静态语言中,Java也是面向对象编程,Python要比Java的面向对象编程更加彻底.元类编程以及猴子补丁都是用一切皆对象编程出来的. 1.函数和类 ...

  3. 关于Java运行机制

    目录 编译型语言与解释型语言的区别 编译型语言 解释型语言 细数两者之差别 Java的奇怪之处 Java的编译 Java的解释 具体机制 Java既是编译型语言,也是解释型语言. 首先先查找关于两种语 ...

  4. MySql分库分表与分区的区别和思考

    一.分分合合 说过很多次,不要拘泥于某一个技术的一点,技术是相通的.重要的是编程思想,思想是最重要的.当数据量大的时候,需要具有分的思想去细化粒度.当数据量太碎片的时候,需要具有合的思想来粗化粒度. ...

  5. Qt事件分发机制源码分析之QApplication对象构建过程

    我们在新建一个Qt GUI项目时,main函数里会生成类似下面的代码: int main(int argc, char *argv[]) { QApplication application(argc ...

  6. js学习——1

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  7. 漫谈LiteOS之开发板-GPIO(基于GD32450i-EVAL)

    [摘要] 本文主要从GPIO的定义.工作模式.特色.工作场合.以及GD32450i-EVAL开发板的引脚.对应的寄存器以及GPIO的流水灯示例对GPIO加以介绍,希望对你有所帮助. 1定义 GPIO( ...

  8. MySQL必知必会(数据分组,Group by和Having子句, Select子句的顺序)

    SELECT vend_id, COUNT(*) AS num_prods FROM products #GROUP BY子句可以包含任意数目的列,多行NULL值将分为一组 GROUP BY vend ...

  9. android 点击无效验证

    背景 在写一个东西滑动删除列表的时候,出现了一个问题.我的需求是,左滑然后出现delete,然后点击delete,让该滑块消失. 我在点列表的第一行的时候,左滑,出现delete,点击删除,ok的,完 ...

  10. 报错 Please make sure you have the correct access rights and the repository exists (git 添加ssh密钥 )

    1.设置Git的user name和email $ git config --global user.name "wubaiwan" $ git config --global u ...