C语言,指针详解

news2024/11/29 12:34:53

1. 指针是什么?

1. 指针是内存中一个最小单元的编号

在这里插入图片描述

2. 口头上的“指针”,指的是指针变量
#include<stdio.h>

int main()
{
    int a=10;
    int * pa=&a;// pa 是一个指针变量,用来存放 a 的地址
    //int ——> pa 所指向对象的类型
    //* 代表 pa是个指针变量
    
    return 0;
}
3. 编址

在这里插入图片描述

4. 指针变量大小
//32位机器上,地址是32个0/1组成的二进制序列,地址要用4个字节的空间来储存


//指针在32位平台上,占4个字节
//在64位平台上,占8个字节

2. 指针和指针类型

1. 内存中的信息

2. 指针类型的意义
2.1[

在这里插入图片描述

//指针的类型,决定了指针解引用时,访问多少个字节 —— 指针的访问权限

//short* ——> 2
//int* ——> 4
//float* ——> 4
//double* ——> 8
//...

#include<stdio.h>

int main()
{
    int a=0x11223344;
    //在内存中开辟四个字节的空间;
    //放入44 33 22 11
    //"44" 所占空间的地址 就是 a 的地址
    char* pa=&a;
    *pa=0;
    //将 44 33 22 11 ——> 00 33 22 11
    return 0;
}
2.2

//指针的类型决定了 指针+1 操作时的步长
//
//char* 类型的指针 +1时,跳过 1  个字节
//int* 类型的指针 +1时,跳过 4 个字节
//

//type* p ,p +/- n
//跳过 n* sizeof(type) 个字节

3. 野指针

3.1

1. 指针未初始化
#include<stdio.h>

int main()
{
    int* pa;
    *pa=10;
    //局部变量指针未初始化,为随机值
    return 0;
}
2. 指针越界访问
#include<stdio.h>

int main()
{
    int arr[10]={0};
    for(int i=0;i<11;i++)
    {
        *(p++)=i;
        //i=10,指针的指向超出了数组范围 ,此时为野指针
    }
    return 0;
}
3. 指针所指向的空间释放
#include<stdio.h>

int* test()
{
    int a=10;
    return &a;
}

int main()
{
    int* p=test();
    printf("%d\n",*p);
    //出test()后,a所在空间还给操作系统了
    //此时 p 为野指针
    return 0; 
}

3.2 规避野指针

1. 指针初始化
#include<stdio.h>

int main()
{
    int a=0;
    int* pa=&a;
    
    int* pc=NULL;//如果不知道指针初始化为何值,暂时初始化为 NULL
    return 0;
}
2. 指针指向的空间释放,及时置 NULL
#include<stdio.h>

int* test()
{
    int a=10;
    return &a;
}

int main()
{
    //避免返回局部变量的地址
    int* p=test();
    
	p=NULL;    
    return 0; 
}
3. 指针使用之前检查有效性
#include<stdio.h>

int main()
{
    int a=10;
    int* pa=&a;
    
    int* ptr=NULL;
    
    if(ptr != NULL)
    {
    	//使用ptr    
	}
    return 0;
}

4. 指针运算

1. 指针加减整数

在这里插入图片描述

//利用指针访问数组中的元素
//1

#include<stdio.h>

int main()
{
    int arr[10]={0};
    int* p=arr;
    
    for(int i=0;i<10;i++)
    {
        *p=i;
        p++;
        //指针不断向后移
    }
    return 0;
}

注意:

在这里插入图片描述

//2
#include<stdio.h>

int main()
{
    int arr[10]={0};
    int* p=arr;

    for(int i=0;i<10;i++)
    {
        *(p+i)=i;
        //指针不移动,利用i++ 对数组中的元素进行访问
	}
    return 0;
}
补充:

" int arr[10] = { 0,1,2,3,4,5,6,7,8,9 };"

arr ——> 数组名 ——> 首元素地址

#include<stdio.h>

int main()
{
    int arr[10]={0,1,2,3,4,5,6,7,8,9};
    int* p=arr;
    for(int i=0;i<10;i++)
        printf("%d ",p[i]);
	return 0;
}

在这里插入图片描述

" arr[i] == *(arr + i) == *(i + arr) == i[arr] "

在这里插入图片描述

//[] ——> 操作符 arr[i] == i[arr]
// + ——> 操作符 a+b == b+a
2. 指针减指针
#include<stdio.h>

int main()
{
    int arr[10]={0};
    printf("%d\n",&arr[9]-&arr[0]);
    return 0;
}

//&arr[9] ——> arr+9
//&arr[0] ——> arr

在这里插入图片描述

//结论:

//1. 指针 - 指针 得到数值的绝对值,是指针与指针之间的元素个数
//2. 指针 - 指针 运算的前提条件是:指针和指针指向了同一块空间

补充:

//my_strlen() 的多种实现方式
#include<stdio.h>

int my_strlen(char ch[])
{
    int len=0;
    while(*ch)
    {
        len++;
        ch++;
    }
    return len;
}

#include<stdio.h>

int my_strlen(char ch[])
{
    int i=0;
    while(*(ch+i))
    {
        i++;
    }
    return i;
}


#include<stdio.h>

int my_strlen(char ch[])
{
    char* start=ch;
    while(*ch)
    {
        //判断 *ch!='\0', ch++
        ch++;
	}
    return ch-start;
}

//err
//while(*ch++)
3. 指针关系运算
//指针是有大小的
//指针关系运算就是比较指针大小
#include<stdio.h>

int main()
{
    int arr[5]={0};
    for(int* p=arr;p<&arr[5];)
        *p++=1;
    
    for(int i=0;i<5;i++)
        printf("%d ",arr[i]);
    return 0;
}

在这里插入图片描述

在这里插入图片描述

C语言标准规定:

允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置进行比较;

但是不允许与指向第一个元素之前的那个内存位置的指针进行比较。

5. 指针和数组

1. 指针和数组的联系
//数组中,数组名是数组首元素地址
//数组是连续存放的

//当我们知道数组首元素地址时,可以通过指针访问数组

6. 二级指针

在这里插入图片描述

在这里插入图片描述

//可以通过修改 **ppa ——> 修改 a 

7. 指针数组

1. 指针数组 ——> 用来存放指针的数组
#include<stdio.h>

int main()
{
    int arr1[]={1,2,3,4,5};
    int arr2[]={2,3,4,5,6};
    int arr3[]={3,4,5,6,7};
    
    int* parr[]={arr1,arr2,arr3};
    return 0;
}

//parr[] 就是一个指针数组
通过指针数组 打印字符串

在这里插入图片描述

2. 指针数组模拟二维数组

在这里插入图片描述

真实的二维数组是连续的

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/606959.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【ros/ros2】ros2 humble镜像制作过程中碰到的问题记录

文章目录 序言1. 避免手动设置时区2. docker build中间某一步失败了3. sudo apt install ros-humble-desktop安装报错 E: Unable to locate package ros-humble-desktop4. 编译ros2 humnble时报错5. sudo rosdep init失败6. 下载依赖时失败&#xff1a;rosdep install --from-p…

局域网技术

共享信道的分配技术是局域网的核心技术&#xff0c;而这一技术又与网络的拓扑结构和传输介质有关。 拓扑结构&#xff1a; 1.总线型拓扑&#xff1a; 总线一种多点广播介质&#xff0c;所有的站点通过接口硬件连接到总线上。 传输介质主要是同轴电缆&#xff08;基带和宽带…

chatgpt赋能python:Python取消空格:如何优化代码和改善SEO?

Python取消空格&#xff1a;如何优化代码和改善SEO&#xff1f; 如果你是一位有10年python编程经验的工程师&#xff0c;那么你一定深刻体会到代码的质量对软件应用的重要性。而在今天&#xff0c;随着搜索引擎优化&#xff08;SEO&#xff09;的发展和对网页排名的更高要求&a…

FastBup:计算机视觉大型图像数据集分析工具

0.简介 官方github网址项目目的&#xff1a;当前大规模图像数据集一团糟&#xff0c;数据量巨大但质量堪忧&#xff0c;有时候训练集、验证集、测试集会有重复数据造成数据泄露。FastBup可以识别重复项、近似重复项、异常图像、错误标注、异常值&#xff0c;在cpu上就可以处理…

Apache Kafka - 流式处理

文章目录 概述什么是流式处理流式处理的一些概念时间状态流和表的二元性时间窗口 流式处理的设计模式单个事件处理使用本地状态多阶段处理和重分区使用外部查找——流和表的连接流与流的连接乱序的事件重新处理 概述 Kafka被广泛认为是一种强大的消息总线&#xff0c;可以可靠…

Zabbix(一)

介绍 zabbix是一个基于WEB界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案。 功能组件 Server &#xff1a; Zabbix server是zabbix软件的核心组件 Zabbix agent向其报告可用性、系统完整性和统计信息 Zabbix server存储所有的配置信息、统计信息和操作信…

chatgpt赋能python:Python取出列表中的若干元素

Python取出列表中的若干元素 Python是一个功能强大且易于学习的编程语言&#xff0c;具有广泛的应用领域。在数据科学和机器学习中&#xff0c;Python是一个非常流行的语言&#xff0c;因为它具有许多用于处理数据和矩阵运算的库&#xff0c;例如NumPy和pandas。在Python的列表…

chatgpt赋能python:使用Python向微信发送信息的方法详解

使用Python向微信发送信息的方法详解 Python作为一种广泛应用于科学计算、数据处理等多个领域的编程语言&#xff0c;也可以用于自动化工作流程和自动发送微信消息等操作&#xff0c;大大提高了工作效率。如果你想在日常工作中用Python向微信群或个人发送自定义信息&#xff0…

linux网络设置

文章目录 一、查看网络配置1.查看网络接口信息——ifconfig1.1查看所有本机的网络的网络设备1.2设置网络接口参数1.3对指定的设备开启或关闭 2.查看主机名称——hostname2.1查看或临时设置当前主机名2.2永久设置主机名 3.查看路由表条目——route3.1查看当前主机路由表3.2添加路…

chatgpt赋能python:Python取消赋值:让你的代码更清晰简洁

Python取消赋值&#xff1a;让你的代码更清晰简洁 在Python编程中&#xff0c;我们经常需要使用赋值语句对变量进行赋值。但在某些情况下&#xff0c;我们也会发现需要取消赋值&#xff0c;即将已经赋过值的变量重新设为未赋值状态。这时&#xff0c;Python提供了一种特殊的语…

阿里云 Windows Server 2022 安装 Docker

阿里云Windows Server 2022 安装 Docker 文章目录 情景尝试正解 安装Docker管理工具安装Docker重启系统配置Docker系统路径配置Docker引擎(也许不用)启动Docker服务 情景 情景&#xff1a;最近一直在搞微服务&#xff0c;团队的服务器是阿里云的 Windows Server 2022&…

chatgpt赋能python:Python发展史:从诞生到井喷的开源之路

Python发展史&#xff1a;从诞生到井喷的开源之路 1. Python诞生的背景和历史 Python作为一种高级动态编程语言&#xff0c;在世界上得到了广泛应用&#xff0c;其诞生与发展也是有着自己的背景和历史的。20世纪90年代初期&#xff0c;著名的荷兰数学家Guido van Rossum开发了…

操作系统之文件管理

目录 认识文件管理 文件的逻辑结构 文件目录 文件的物理结构 文件存储空间管理 文件的基本操作 文件共享 文件保护 文件系统的全局结构 虚拟文件系统 内容摘自&#xff1a;4.1_1_初识文件管理_哔哩哔哩_bilibili 认识文件管理 文件——就是一组有意义的信息/数据集合…

chatgpt赋能python:Python可以用C语言吗?——一份详细解读

Python可以用C语言吗&#xff1f;——一份详细解读 Python和C语言是两种常见而重要的编程语言。Python被广泛应用于各种领域&#xff0c;从人工智能到数据科学&#xff0c;而C语言则是系统编程&#xff0c;操作系统和编译器方面最受欢迎的语言之一。许多人认为Python和C语言没…

pikachu靶场总结

目录 一.暴力破解 1.基于表单的暴力破解 2.验证码绕过&#xff08;on server&#xff09; 3.验证码绕过&#xff08;client&#xff09; 4.token防爆破 二.Cross-Site Scripting 1.先了解XSS 2.反射型xss&#xff08;get&#xff09; 3.反射型xss&#xff08;post&…

[SPSS] SPSS统计分析软件简介

SPSS的英文缩写来源于以下两个 ① Statistical Package for Social Science(社会科学统计软件包) ② Statistical Product and Service Solutions(统计产品与服务解决方案) SPSS是一种专业的统计分析软件。为用户提供了直观的图形化菜单界面&#xff0c;用户的数据管理和统计…

C++——多态与虚表

目录 1.多态的实现 2.虚表 2.1虚函数重写是怎么实现的 2.2多态的原理 2.3静态绑定与动态绑定 3.单继承体系中的虚函数表 ​编辑4.多继承体系中的虚函数表 5.菱形继承的虚函数表 6.菱形虚拟继承的虚函数表 1.多态的实现 在C中&#xff0c;要想实现多态&#xff0c;必…

认识elasticSearch并安装

一、介绍 定义&#xff1a;简称es&#xff0c;本质是一个开源的nosql数据库。主要用于全文检索&#xff0c;所以我们又称它为搜索引擎框架&#xff1b; 用途&#xff1a;实时数据搜索、日志采集分析 特点&#xff1a; 检索快。面对PB级的海量数据&#xff0c;用传统sql方式…

solr快速上手:配置从mysql同步数据(五)

0. 引言 上一节我们已经配置了新的索引&#xff0c;但是数据还是手动添加的&#xff0c;并没有实现自动从数据库同步&#xff0c;所以这一节&#xff0c;继续来实现从mysql同步数据到solr solr快速上手&#xff1a;solr简介及安装&#xff08;一&#xff09; solr快速上手&a…

chatgpt赋能python:Python中取某个元素的技巧

Python 中取某个元素的技巧 作为一种强大而灵活的编程语言&#xff0c;Python 常常被用来处理各种数据集合&#xff0c;如列表、元组、字典等。在处理这些数据集合的过程中&#xff0c;取某个元素的需求很常见&#xff0c;同时也有多种实现方法。在本文中&#xff0c;我们将介…