首页 > 其他分享 >C语言指针详解(初级)

C语言指针详解(初级)

时间:2024-07-16 16:55:02浏览次数:19  
标签:变量 int C语言 vp 地址 详解 数组 指针

1. 指针是什么?


指针理解的 2 个要点:
        1. 指针是内存中一个最小单元的编号,也就是地址(&)         2. 平时口语中说的指针,通常指的是指针变量,是用来存放内存地址的变量 总结:指针就是地址,口语中说的指针通常指的是指针变量。 那我们就可以这样理解:         内存(如图所示):

1.1指针变量

我们可以通过 & (取地址操作符)取出变量的内存起始地址,把地址可以存放到一个变量中,这个 变量就是指针变量 int main() {  int a = 10;//在内存中开辟一块空间  int* p = &a;//这里我们对变量a,取出它的地址,可以使用&操作符。  //a变量占用4个字节的空间,这里是将a的4个字节的第一个字节的地址存放在p变量  //中,p就是一个之指针变量。  return 0; } 总结: 指针变量,用来存放地址的变量。(存放在指针中的值都被当成地址处理)。

2. 指针和指针类型

        我们都知道,在c语言中变量有不同的类型,整形,浮点型等。那指针有没有类型呢? 准确的说:有的!
当有这样的代码:
int num = 10 ; p = & num ;
要将 &num ( num 的地址)保存到 p 中,我们知道 p 就是一个指针变量,那它的类型是怎样的呢? 我们给指针变量相应的类型。
char   * pc = NULL ; int   * pi = NULL ; short * ps = NULL ; long   * pl = NULL ; float * pf = NULL ; double * pd = NULL ;
这里可以看到,指针的定义方式是: type + *  其实: char* 类型的指针是为了存放 char 类型变量的地址。 short* 类型的指针是为了存放 short 类型变量的地址。 int* 类型的指针是为了存放 int 类型变量的地址。 那指针类型的意义是什么?

2.1 指针+-整数

总结: 指针的类型决定了指针向前或者向后走一步有多大(距离)

2.2 指针的解引用

总结: 指针的类型决定了,对指针解引用的时候有多大的权限(能操作几个字节) 比如: char* 的指针解引用就只能访问一个字节,而 int* 的指针的解引用就能访问四个字节。

3. 野指针

        概念: 野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)

3.1 野指针成因

        1. 指针未初始化

注意:在vs2022上是打印不出来随机值的,在Dev,小熊猫编译器上可以打印出随机值  知道即可!         

        2. 指针越界访问

如图所示,超出了数组的范围,就找不到啦!!!

3.2 如何规避野指针

        1. 指针初始化         2. 小心指针越界         3. 指针指向空间释放,及时置 NULL         4. 避免返回局部变量的地址         5. 指针使用之前检查有效性

4. 指针运算

  • 指针 +- 整数
  • 指针 - 指针
  • 指针的关系运算

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. 指针和数组

        看一个示例:

看到运算结果,我们可想而知 可见数组名和数组首元素的地址是一样的。 结论数组名表示的是数组首元素的地址 。 那么这样写代码是可行的:

int arr [ 10 ] = { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 0 }; int * p = arr ;
既然可以把数组名当成地址存放到一个指针中,我们使用指针来访问一个就成为可能。 例如:
#include <stdio.h>
int main()
{
    int arr[] = {1,2,3,4,5,6,7,8,9,0};
    int *p = arr; //指针存放数组首元素的地址
    int sz = sizeof(arr)/sizeof(arr[0]);
    for(i=0; i<sz; i++)
   {
        printf("&arr[%d] = %p   <====> p+%d = %p\n", i, &arr[i], i, p+i);
   }
    return 0;
}

运算结果如下:

所以 p+i 其实计算的是数组 arr 下标为 i 的地址。 那我们就可以直接通过指针来访问数组。 如下:

6. 二级指针

        想一个问题: 指针变量也是变量,是变量就有地址,那指针变量的地址存放在哪里?         想到了嘛?          这就是 二级指针 ! 如图所示: 看图得出, a的地址存放在*pa里面,*pa的地址存放在**ppa中 对于二级指针的运算有: *ppa 通过对 ppa 中的地址进行解引用,这样找到的是 pa , *ppa 其实访问的就是 pa .
int b = 20 ; * ppa = & b ; // 等价于 pa = &b;
**ppa 先通过 *ppa 找到 pa , 然后对 pa 进行解引用操作: *pa ,那找到的是 a .
** ppa = 30 ; // 等价于 *pa = 30; // 等价于 a = 30;
懂?

7. 指针数组

          指针数组是指针还是数组?  答案:是数组。是存放指针的数组。   数组我们已经知道整形数组,字符数组。
int arr1 [ 5 ]; char arr2 [ 6 ];
那指针数组是怎样的?
         int* arr3 [ 5 ]; // 是什么?
arr3 是一个数组,有五个元素,每个元素是一个整形指针。 数组指针详情待下篇分享!!

本篇文章到此就结束啦!   

小磊在此问候大家  还请各位大佬三连!!!丞退了

标签:变量,int,C语言,vp,地址,详解,数组,指针
From: https://blog.csdn.net/L286594/article/details/140464715

相关文章

  • C++(函数参数为数组与指针算术)
    目录1.函数参数为数组2.指针算术2.1arr是指向第一个元素的地址2.2arr[i]表示什么?#include<iostream>voidprintArray(intarr[],intsize){for(inti=0;i<size;++i){std::cout<<arr[i]<<"";}}intmain(){intarr[5]......
  • C语言网络编程(一对多通讯)
    使用C语言实现一个服务器对多个客户端主要技术除了网络编程几个函数的使用外,还用到了线程,实现方式是一个客户端对应一个新的线程Server:#include<pthread.h>//包含线程库的头文件#include<stdio.h>#include<sys/types.h>#include<sys/socket.h>#include<arpa/inet.h......
  • Java中的网络编程与TCP/IP协议详解
    Java中的网络编程与TCP/IP协议详解大家好,我是微赚淘客系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!在现代软件开发中,理解和掌握网络编程以及TCP/IP协议是构建高性能网络应用的关键。本文将深入讨论Java中的网络编程技术和TCP/IP协议的工作原理与应用。一、网络编程基础......
  • C++ 用智能指针这样包装 this 指针是否可行
    #include<iostream>#include<memory>usingnamespacestd;classA;classB{public:B(shared_ptr<A>a){pa=a;cout<<"B构造..."<<endl;}~B(){cout<<&quo......
  • python接口自动化(二十八)--html测试 报告——下(详解)
    宏哥微信粉丝群:https://bbs.csdn.net/topics/618423372 有兴趣的可以扫码加入1.简介五一小长假已经结束了,想必大家都吃饱喝足玩好了,那就继续学习吧。一天不学习,自己知道;两天不学习,对手知道;三天不学习,大家知道;一周不学习,智商输给猪。好了开个玩笑都逗大家一乐,但是想想还......
  • 【热门】用 Java 构建高并发电子商务网站(深入研究+详解代码)
    书接上回,想必大家都对该类型的话题很感兴趣。是的,这个话题确实很热门,它也有很多优点。好的,接下来我们进行深入研究。本作品由老程个人著作,仅供参考以下是一个简单的JavaWeb应用示例,结合优化建议进行了逐步的优化和讲解:importjava.sql.Connection;importjava.sql.D......
  • SpringAOP中的切点表达式Pointcut详解
    https://www.jb51.net/program/293999439.htm 一、概述SpringAOP只支持SpringBean的方法切入,所以切点表达式只会匹配Bean类中的方法。二、切点表达式配置1.内置配置定义切面通知时,在 @Before 或 @AfterReturning 等通知注解中指定表达式。12345......
  • 注意力机制中三种掩码技术详解和Pytorch实现
    注意力机制是许多最先进神经网络架构的基本组成部分,比如Transformer模型。注意力机制中的一个关键方面是掩码,它有助于控制信息流,并确保模型适当地处理序列。在这篇文章中,我们将探索在注意力机制中使用的各种类型的掩码,并在PyTorch中实现它们。在神经网络中,掩码是一种用于阻止模......
  • 《死亡搁浅》DX12报错怎样处理,游戏DX12报错解决教程详解
    《死亡搁浅》作为一款广受瞩目的开放世界动作冒险游戏,凭其独特剧情设定、精细画面呈现和创新游戏玩法吸引了全球大量玩家。然而在PC平台上,部分玩家尝试运行此游戏时却遭遇和DX12有关的报错问题,致使游戏无法正常启动或运行中频繁崩溃。本篇将为大家带来《死亡搁浅》DX12报错解决......
  • 机器学习策略篇:详解处理数据不匹配问题(Addressing data mismatch)
    处理数据不匹配问题如果您的训练集来自和开发测试集不同的分布,如果错误分析显示有一个数据不匹配的问题该怎么办?这个问题没有完全系统的解决方案,但可以看看一些可以尝试的事情。如果发现有严重的数据不匹配问题,通常会亲自做错误分析,尝试了解训练集和开发测试集的具体差异。技术上......