首页 > 其他分享 >02-指针入门

02-指针入门

时间:2023-06-23 19:12:35浏览次数:32  
标签:02 vp 入门 int char 数组 printf 指针

目录

一.什么是指针

1.1 指针的两种含义

  • 指针是内存中最小单元的编号, 也就是地址
  • 平时口语上的指针, 实际上是指针变量, 用来存放内存地址的变量.

1.2 指针表示含义

  • 指针表示细节
//以下这两种写法都是可以的, 但是第一种更加贴合实际含义, 注意保存代码库的风格一致性即可.
char* p = NULL; //这种写法更加强调p是(char*)类型的变量.
char *p = NULL; //这种写法更容易看出p是指针.

总结: 指针就是地址, 平时口头指针是指指针变量

二. 指针类型的意义

2.0 问题引出

  • 在32位机上, 指针都是占4个字节, 那为什么还要分不同的类型, 这4个字节不是可以存储任何类型数据的地址吗?
char* pa = NULL;
int*  pi = NULL;
float* pf = NULL;
...

2.1 不同类型指针步长不同

  • 以下这段代码通过指针加减整数, 来展示不同类型指针的步长.
#include <stdio.h>

int main()
{
 int n = 10;
 char *pc = (char*)&n;
 int *pi = &n;
 
 printf("%p\n", &n);      //0x010FF70C
 printf("%p\n", pc);      //0x010FF70C
 printf("%p\n", pc+1);    //0x010FF70D
 printf("%p\n", pi);      //0x010FF70C
 printf("%p\n", pi+1);    //0x010FF710
 return  0;
}

2.2 不同类型指针解引用的权限不同

  • 从以下这段代码可以清除观察到, char对空间操作的权限只有一个字节, 而int权限是4个字节
#include <stdio.h>

int main()
{
	int n = 0x11223344;
	char* pc = (char*)&n;
	int* pi = &n;

	*pc = 0;
	printf("%#0x\n", n); //0x11223300

	*pi = 0;
	printf("%#0x", n);   //0
	return 0;
}

总结: 指针类型主要有两个作用: 一是决定步长, 二是决定管理空间大小的权限

三. 野指针

3.1 指针未初始化造成野指针

  • 如下代码, p没有指向任何空间, 此时p中未随机值, 这时候指向的空间并没有获得系统的使用权限, 对这块空间赋值就是非法行为.
#include <stdio.h>
int main()
{ 
 int *p;//局部变量指针未初始化,默认为随机值
    *p = 20;
 return 0;
}

3. 2 指针越界访问造成野指针

  • 如下这段代码指针指向的空间越过了数组的范围, 所指向的空间也是没有获得系统使用权限, 会造成非法访问.
#include <stdio.h>
int main()
{
    int arr[10] = {0};
    int *p = arr;
    int i = 0;
    for(i=0; i<=11; i++)
   {
        //当指针指向的范围超出数组arr的范围时,p就是野指针
        *(p++) = i;
   }
    return 0;
}

3.3 指针指向的空间释放(动态内存)

  • 如下代码中ptr被释放后, 再使用pt去指向该空间, 就会造成野指针.
#include <stdio.h>
#include <stdlib.h>

int main() {
    int* ptr = (int*)malloc(sizeof(int));  // 分配动态内存
    *ptr = 10;                             // 在分配的内存中存储值

    free(ptr);                             // 释放动态内存

    int* pt= ptr;                          // 尝试访问已释放的内存
    printf("%d", *pt);

    return 0;
}

3.4 如何规避野指针

  • 指针初始化
  • 小心指针越界
  • 指针空间释放及时置NULL
  • 避免返回局部变量的地址
  • 指针使用之前检测有效性
#include <stdio.h>
int main()
{
    int *p = NULL;
    //....
    int a = 10;
    p = &a;
    if(p != NULL)
   {
        *p = 20;
   }
    return 0;
}

总结: 野指针的形成主要出现在: 一. 指针未初始化. 二. 指针越界访问. 三. 指针指向被释放的内存空间

四. 指针运算

4.1 指针 +- 整数

  • 可以改变指针指向的位置前后
#define N_VALUES 5
float values[N_VALUES];
float *vp;
//指针+-整数;指针的关系运算
for (vp = &values[0]; vp < &values[N_VALUES];)
{
     *vp++ = 0;
}

4.2 指针 - 指针

  • 可以得到两个指针之间的空间大小(注意没有指针 + 指针因为没有实际应用场景)
int my_strlen(char *s)
{
       char *p = s;
       while(*p != '\0' )
              p++;
       return p-s;
}

4.3 指针运算注意事项

  • 实际上我门应该避免以下这种写法: 因为标准规定允许数组元素的指针与数组最后一个元素后面的存储位置的指针比较. 但不允许指向第一个元素的指针, 与其之前的那个内存位置的指针进行比较.
//写法一
for(vp = &values[N_VALUES]; vp > &values[0];)
{
    *--vp = 0;
}

//简化
for(vp = &values[N_VALUES-1]; vp >= &values[0];vp--)
{
    *vp = 0;
}

五. 二级指针和指针数组

5.0 问题引出: 指针变量的地址放在哪里?

  • 下图指针pa的地址, 存放在ppa中, 而ppa就是二级指针变量.

5.1 二级指针运算

  • 主要注意: *ppa 和 **ppa的含义即可
int b = 20;
int* pa = &b
int** ppa = &pa;
*ppa = &b;  //等价于 pa = &b;
**ppa = 30; //等价于 b = 30; 和 *pa = 30;

5.2 数组指针的概念

  • 用于存放指针的数组(本质还是数组, 数组的每个元素都是指针或者说, 数组的每个内存空间都是用于存放指针的)
int arr1[5];
char arr2[6];

int* arr3[5];    //数组每个元素都是int*(整形指针类型)
char* arr4[6];   //数组每个元素都是char*(字符指针类型)

标签:02,vp,入门,int,char,数组,printf,指针
From: https://www.cnblogs.com/Deng-S/p/17499517.html

相关文章

  • 2021年最新-可解释机器学习相关研究最新论文、书籍、博客、资源整理分享
        理解(interpret)表示用可被认知(understandable)的说法去解释(explain)或呈现(present)。在机器学习的场景中,可解释性(interpretability)就表示模型能够使用人类可认知的说法进行解释和呈现。[FinaleDoshi-Velez]    机器学习模型被许多人称为“黑盒”。这意味着虽然我们可以从......
  • 2021年3月最新-李沐-动手学深度学习第二版-中、英文版
        阿斯顿·张、李沐联合编写的,面向中文读者的能运行、可讨论的深度学习教科书《动手学深度学习》又更新了。 【关注第二版更新】 英文版前八章已翻译至中文版第二版,并含多种深度学习框架的实现。英文版还新增了注意力机制、BERT、 自然语言推理、 推荐系统和深度学习的数......
  • 2021ML实战新-深度学习速成2021
    课程描述    该课程为深度学习提供了实用的入门知识,包括理论动机以及如何在实践中进行实践。作为课程的一部分,我们将介绍多层感知器,反向传播,自动微分和随机梯度下降。此外,我们介绍了用于图像处理的卷积网络,从简单的LeNet到更新的体系结构(例如ResNet),以提供高度精确的模型。其次,......
  • 蒂宾根大学-机器学习导论2021
    课程描述    该课程是机器学习的基础入门,涵盖回归,分类,优化,正则化,聚类和降维的关键概念。该课程面向神经科学和其他科学领域的硕士生。本课程假定您对微积分,概率论和线性代数(矩阵)有基本了解。 课程大纲  课程视频截图......
  • 李宏毅最新-深度学习/机器学习课程2021-课程视频及ppt
    课程描述    由国立台湾大学李宏毅老师主讲的纯中文版,2021年机器学习(深度学习)开课了,课程相关的部分资源已经release出来了,今年课程新增了很多新的前沿的内容,分享给大家。  课程大纲课程主页https://speech.ee.ntu.edu.tw/~hylee/ml/2021-spring.html 课程视频截图 ......
  • 2021年最新-深度学习必备基础理论
    本书介绍    本简书主要所包含两个部分的内容。   1.是为文献中出现的内容提供简化的证明,希望将困难的事情简化为适合一堂课的内容。        2.主要关注的是通过标准(典型的ReLU)前馈网络实现IID数据二进制分类的低测试误差。               ......
  • 自然语言处理顶会ACL 2020会议核心要点分享
        今年受疫情影响,ACL只能举行线上虚拟会议,因此不能近距离跟行业学者们进行交流。但我任然想把我了解到的ACL的争取趋势和研究动态分享处理,因而有了这篇文章。     这些年来ACL的总体趋势    在开始讨论整个趋势之前之前,让我们先看一下ACL会议的一些总体统计数据。今......
  • 2020年最值得阅读的10本人工智能相关书籍
        尽管我们都可以通过快速的YouTube视频或博客文章来学习,但是全神贯注于阅读一本好书有时还是不错的。因此,整理了一些最近深度学习“必读”的翻页书,以备你在世界读书日阅读!       1. GirlDecoded    RanaelKaliouby和CarolColman   Affectiva首席执行官......
  • 斯坦福2020年免费新课-CS221人工智能原理与技术-视频、ppt、参考书籍分享
        分享一套斯坦福大学在2020年初,2019年底放出一门免费精品课程-人工智能原理与技术课程,对于对于春节想要系统学习人工智能知识朋友绝对不容错过。课程介绍    这门课主要讲什么?网络搜索、语音识别、人脸识别、机器翻译、自动驾驶和自动调度有什么共同之处呢?这些都是复杂......
  • 指针详解
    一、指针运算给一个指针变量+1,通常情况下不是给指针本身+1,而是”迈一步“,步长根据指针的类型来确定。intmain(){ chara=1; intb=1; intarr[10]={0}; char*pa=&a; int*pb=&b; int(*parr)[10]=&arr; printf("%p\n",pa); printf("%p\n",pa+1);//......