【c语言指针详解】指针的基本概念和用法

news2024/11/26 10:42:40

目录

一、指针的基本概念和用法

二、指针运算

2.1 指针的自增和自减运算

2.2 指针的自增和自减运算

三、数组和指针

四、指针和函数

4.1 在函数中使用指针作为参数和返回值

4.1.1 使用指针作为函数参数

4.1.2 使用指针作为函数返回值

4.2 指针参数的传值和传引用特性

4.2.1 指针参数的传值特性

4.2.2 指针参数的传引用特性


🌈嗨!我是Filotimo__🌈。很高兴与大家相识,希望我的博客能对你有所帮助。

🎁欢迎大家给我点赞👍、收藏⭐️,并在留言区📝与我互动,这些都是我前进的动力!

🌟我的格言:森林草木都有自己认为对的角度🌟。

一、指针的基本概念和用法

在 C 语言中,指针是一个变量,用来存储一个地址,这个地址指向内存中的另外一个变量。可以通过指针来访问或修改这个变量的值。

使用 * 运算符可以访问指针所指向的变量的值。

使用 & 运算符可以获取变量的地址。

下面是一个使用指针访问变量地址和值的示例代码:

#include <stdio.h>

int main() {
    int num = 42;       // 定义一个整数变量 num 并初始化为 42
    int *ptr = &num;    // 定义一个指针变量 ptr 并将其初始化为 num 的地址

    printf("num 的地址是:%p\n", &num);
    printf("ptr 所指向的地址是:%p\n", ptr);
    printf("ptr 所指向的值是:%d\n", *ptr);

    return 0;
}

输出结果如下:

在上面的示例代码中,我们首先定义了一个整型变量 num 并初始化赋值为 42,然后定义一个整型指针变量 ptr ,并使用 & 运算符取 num 变量的地址初始化 ptr 指向 num 变量的地址。接着我们通过 printf 函数输出 num 变量的地址和 ptr 指向的地址,最后输出通过 *ptr 来访问 ptr 指向的变量 num 的值。

二、指针运算

2.1 指针的自增和自减运算

自增和自减运算仅适用于指向数组、字符串或分配内存的指针。

自增运算符 ++ 让指针指向下一个内存单元,即指针变量的值加上所指向的变量类型占用的字节数。

自减运算符 -- 让指针指向前一个内存单元,即指针变量的值减去所指向的变量类型占用的字节数。

示例代码:

#include <stdio.h>

int main() {
    int arr[5] = {1, 2, 3, 4, 5};
    int *p = &arr[0];   // 指向数组 arr 的第一个元素的指针

    printf("当前指针 p 的值为: %p\n", p);
    p++;                // 指针自增操作
    printf("执行 p++ 后,p 指向的值为: %d\n", *p);

    p--;                // 指针自减操作
    printf("执行 p-- 后,p 指向的值为: %d\n", *p);

    return 0;
}

输出结果如下:

这段代码中,我们定义了一个包含 5 个整型元素的数组 arr,并定义一个指向数组第一个元素的指针 p。通过执行 p++ 和 p-- 操作,指针 p 的值发生了变化,指向了数组中不同的元素,从而可以访问数组中不同的数据。

2.2 指针的自增和自减运算

加法和减法运算可以应用于指向数组或分配内存的指针。如果对指针进行加法或减法运算,会根据指针所指向类型的字节大小来确定位移量。

指针的加法运算(+)将指针的值增加多个字节数。

指针的减法运算(-)将指针的值减去多个字节数。

示例代码:

#include <stdio.h>

int main() {
    int arr[] = {1, 2, 3, 4, 5};
    int *p = &arr[2];   // 指向数组 arr 的第三个元素的指针

    printf("当前指针 p 的值为: %p\n", p);
    
    p = p + 1;          // 指针加法操作
    printf("执行 p + 1 后,p 指向的值为: %d\n", *p);
    
    p = p - 2;          // 指针减法操作
    printf("执行 p - 2 后,p 指向的值为: %d\n", *p);

    return 0;
}

输出结果如下:

在这个示例中,我们定义了一个数组 arr,并将指针 p 初始化为指向数组 arr 的第三个元素。通过执行 p + 1 和 p - 2 操作,指针 p 的值发生了相应的变化,通过访问指针 p 所指向的值,我们可以看到指针指向了数组中不同的元素。

三、数组和指针

数组名本身就是指向数组头部的指针。

例如,如果有一个 int 类型的数组 arr,那么在代码中使用 arr 和 &arr[0] 是等效的,在内存中它们所指向的都是数组的第一个元素。

示例代码:

#include <stdio.h>

int main() {
    int arr[] = {1, 2, 3, 4, 5};
    int *p = arr;       // 指向数组 arr 的第一个元素的指针

    printf("通过数组名访问数组的第一个元素:%d\n", arr[0]);
    printf("通过指针访问数组的第二个元素:%d\n", *(p + 1));
    printf("通过指针访问数组的第三个元素:%d\n", p[2]);

    return 0;
}

输出结果如下:

四、指针和函数

4.1 在函数中使用指针作为参数和返回值

4.1.1 使用指针作为函数参数

可以通过将指针作为函数的参数来传递数据。这样可以实现在函数内部修改传递给函数的变量的值,因为指针传递的是变量的地址。

示例代码:

#include <stdio.h>

void changeValue(int *ptr) {
    *ptr = 10;   // 修改指针指向的变量的值
}

int main() {
    int num = 5;
    printf("函数调用前的值:%d\n", num);
    changeValue(&num);   // 传递变量的地址
    printf("函数调用后的值:%d\n", num);
    
    return 0;
}

输出结果如下:

在这个示例中,我们在 changeValue 函数中使用了一个指针参数 ptr,通过 *ptr 修改了变量 num 的值。在 main 函数中将 num 的地址传递给 changeValue 函数来实现修改 num 的值。

4.1.2 使用指针作为函数返回值

可以使用指针作为函数的返回值,以便将函数内部的计算结果返回给调用函数。

示例代码:

#include <stdio.h>
#include <stdlib.h>   // 包含 malloc 和 free 函数

int* createArray(int size) {
    int *arr = (int*)malloc(size * sizeof(int));   // 动态分配内存,并强制类型转换
    for (int i = 0; i < size; i++) {
        arr[i] = i + 1;
    }
    return arr;
}

int main() {
    int size = 5;
    int *array = createArray(size);   // 函数返回指针
    for (int i = 0; i < size; i++) {
        printf("%d ", array[i]);
    }
    free(array);   // 释放内存
    
    return 0;
}

输出结果如下:

在这个示例中,createArray 函数根据传入的参数 size 动态分配了一个整型数组,并将数组的首地址作为指针返回给调用函数。在 main 函数中,我们通过调用 createArray 函数来获取数组的地址,并使用指针 array 访问和输出数组的元素。最后,释放动态分配的内存。

4.2 指针参数的传值和传引用特性

4.2.1 指针参数的传值特性

当将指针作为函数参数进行传递时,实际上传递的是指针变量的值(即地址)。这意味着函数内部对指针本身的修改不会影响到调用该函数的代码。

示例代码:

#include <stdio.h>

void changePointer(int *ptr) {
    int dummy = 10;
    ptr = &dummy;   // 修改指针的值
}

int main() {
    int num = 5;
    int *ptr = &num;
    printf("函数调用前的指针:%p\n", ptr);
    changePointer(ptr);
    printf("函数调用后的指针:%p\n", ptr);

    return 0;
}

输出结果如下:

在这个示例中,changePointer 函数尝试将指针 ptr 指向一个新的变量 dummy,但是在函数外部输出指针 ptr 的值时并未改变,验证了指针参数的传值特性。

4.2.2 指针参数的传引用特性

通过使用指针的指针或者指针的引用,可以实现对指针的引用传递,从而在函数内部对指针进行修改可以影响到调用该函数的代码。

示例代码:

#include <stdio.h>

void changePointer(int **ptr) {
    int dummy = 10;
    *ptr = &dummy;   // 修改指针指向的地址
}

int main() {
    int num = 5;
    int *ptr = &num;
    printf("函数调用前的指针:%p\n", ptr);
    changePointer(&ptr);
    printf("函数调用后的指针:%p\n", ptr);

    return 0;
}

输出结果如下:

在这个示例中,我们将指针 ptr 的地址传递给 changePointer 函数,并在函数内部修改了指针 ptr 的值为新的变量 dummy 的地址。在函数外部输出指针 ptr 的值时发现已经改变,验证了指针参数的传引用特性。

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

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

相关文章

Windows 系统,TortoiseSVN 无法修改 Log 信息解决方法

使用SVN提交版本信息时&#xff0c;注释内容写的不全。通过右键TortoiseSVN的Show log看到提交的的注释&#xff0c;右键看到Edit log message的选项&#xff0c;然而提交后却给出错误提示&#xff1a; Repository has not been enabled to accept revision propchanges; ask …

【模型量化】神经网络量化基础及代码学习总结

1 量化的介绍 量化是减少神经网络计算时间和能耗的最有效的方法之一。在神经网络量化中&#xff0c;权重和激活张量存储在比训练时通常使用的16-bit或32-bit更低的比特精度。当从32-bit降低到8-bit&#xff0c;存储张量的内存开销减少了4倍&#xff0c;矩阵乘法的计算成本则二…

Mint Blockchain,一个聚焦在 NFT 领域的 L2 网络

Mint 是什么&#xff1f; Mint 是一个聚焦在 NFT 领域的创新型 L2 网络。Mint Blockchain 致力于促进 NFT 资产协议标准的创新和现实商业场景中 NFT 资产的大规模采用。 不管是过去 3 年在以太坊网络涌现的 NFT&#xff0c;还是当下在比特币网络活跃的“铭文” NFT&#xff0c…

HarmonyOS开发(九):数据管理

1、概述 1.1、功能简介 数据管理为开发者提供数据存储、数据管理能力。 它分为两个部分&#xff1a; 数据存储&#xff1a;提供通用数据持久化能力&#xff0c;根据数据特点&#xff0c;分为用户首选项、键值型数据库和关系型数据库。数据管理&#xff1a;提供高效的数据管…

gitlab注册无中国区电话验证问题

众所周知gitlab对中国区不友好&#xff0c;无法直接注册&#xff0c;页面无法选择86的手机号进行验证码发送。 Google上众多的方案是修改dom&#xff0c;而且时间大约是21年以前。 修改dom&#xff0c;对于现在的VUE、React框架来说是没有用的&#xff0c;所以不用尝试。 直接看…

springboot3远程调用

RPC 两个服务器之间的调用 远程请求 内部服务之间的调用 可以通过 cloud 注册中心 openfeign等 外部服务的调用 http请求 外部协议 api:远程接口 sdk&#xff1a;本地调用 调用阿里云的天气请求

Navicat 技术指引 | 适用于 GaussDB 分布式的日志查询与配置设置

Navicat Premium&#xff08;16.3.3 Windows 版或以上&#xff09;正式支持 GaussDB 分布式数据库。GaussDB 分布式模式更适合对系统可用性和数据处理能力要求较高的场景。Navicat 工具不仅提供可视化数据查看和编辑功能&#xff0c;还提供强大的高阶功能&#xff08;如模型、结…

Python---random库

目录 基本随机数函数(): rand.seed() random() 扩展随机数函数(): random库包含两类函数&#xff1a;基本随机数函数&#xff0c;扩展随机数函数 基本随机数函数:seed(),random() 扩展随机数函数&#xff1a;randint,getrandbits(),uniform(),randrange(),choice(),shuff…

分布式和微服务区别

1.分布式 微服务和分布式的区别 1.将一个大的系统划分为多个业务模块&#xff0c;业务模块分别部署到不同的机器上&#xff0c;各个业务模块之间通过接口进行数据交互。区别分布式的方式是根据不同机器不同业务。 2.分布式是否属于微服务&#xff1f; 答案是肯定的。微服务的意…

微信小程序引入Vant Weapp修改样式不起作用,使用外部样式类进行覆盖

一、引入Vant Weapp后样式问题 在项目中使用第三方组件修改css样式时,总是出现各种各样问题,修改的css样式不起作用,没有效果,效果不符合预期等。 栗子(引入一个搜索框组件)实现效果: 左侧有一个搜索文字背景为蓝色,接着跟一个搜索框 wxml <view class"container&q…

cache 2.单机并发缓存

0.对原教程的一些见解 个人认为原教程中两点知识的引入不够友好。 首先是只读数据结构 ByteView 的引入使用是有点迷茫的&#xff0c;可能不能很好理解为什么需要ByteView。 第二是主体结构 Group的引入也疑惑。其实要是熟悉groupcache&#xff0c;那对结构Group的使用是清晰…

修改pip源

修改pip源 永久修改 PS C:\Users\Dell> pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/Writing to C:\Users\Dell\AppData\Roaming\pip\pip.ini临时修改 pip install -i(即--index-url简写) http://mirrors.aliyun.com/pypi/simple/ selenium…

图像叠加中文字体

目录 1) 前言2) freetype下载3) Demo3.1) 下载3.2) 编译3.3) 运行3.4) 结果3.5) 更详细的使用见目录中说明 4) 积少成多 1) 前言 最近在做图片、视频叠加文字&#xff0c;要求支持中文&#xff0c;基本原理是将图片或视频解码后叠加文字&#xff0c;之后做图片或视频编码即可。…

一文讲解关于MCU启动原理的几个关键问题

MCU最开始一启动后去哪里读代码&#xff1f; CPU上电启动后被设计为去地址0x00000000位置处读取代码&#xff1b;首先会连续读取两个字&#xff0c;分别是栈指针初始值和复位异常处理函数的地址&#xff1b;然后跳去执行复位异常处理函数。 当然在一些早期的ARM处理器设计中&a…

【计算机网络学习之路】HTTP请求

目录 前言 HTTP请求报文格式 一. 请求行 HTTP请求方法 GET和POST的区别 URL 二. 请求头 常见的Header 常见的额请求体数据类型 三. 请求体 结束语 前言 HTTP是应用层的一个协议。实际我们访问一个网页&#xff0c;都会像该网页的服务器发送HTTP请求&#xff0c;服务…

nodejs+vue+微信小程序+python+PHP的黄山旅游景点购票系统设计与实现-计算机毕业设计推荐

本文首先对该系统进行了详细地描述&#xff0c;然后对该系统进行了详细的描述。管理人员增加了系统首页、个人中心、用户管理、景点分类管理、景点简介管理、旅游路线管理、文章分类管理、公告文章管理、系统管理理等功能。黄山旅游景点购票系统是根据当前的现实需要&#xff0…

ELK(五)—集群搭建

写目录 ip规划ElasticSearch集群集群节点搭建集群es切片和副本切片&#xff08;Shard&#xff09;&#xff1a;副本&#xff08;Replica&#xff09;&#xff1a; 故障转移postman创建索引的情况直接在面板中创建索引总结 ip规划 ip名称服务192.168.150.190elk_masterelastics…

web漏洞原理与防御策略,web漏洞怎么挖掘

目录 Web安全的重要性 ​编辑常见的Web漏洞类型及其原理&#xff1a; 1、跨站脚本攻击&#xff08;XSS&#xff09;: 2、SQL注入: 3、跨站请求伪造&#xff08;CSRF&#xff09;: 4、远程文件包含&#xff08;RFI&#xff09;和本地文件包含&#xff08;LFI&#xff09;:…

深入浅出:HTTPS单向与双向认证及证书解析20231208

介绍: 网络安全的核心之一是了解和实施HTTPS认证。本文将探讨HTTPS单向认证和双向认证的区别&#xff0c;以及SSL证书和CA证书在这些过程中的作用&#xff0c;并通过Nginx配置实例具体说明。 第一部分&#xff1a;HTTPS单向认证 定义及工作原理&#xff1a;HTTPS单向认证是一…

数据分析基础之《matplotlib(6)—饼图》

一、饼图介绍 1、什么是饼图 饼图广泛的应用在各个领域&#xff0c;用于表示不同分类的占比情况&#xff0c;通过弧度大小来对比各种分类。饼图通过将一个圆饼按照分类的占比划分成多个区块&#xff0c;整个圆饼代表数据的总量&#xff0c;每个区块&#xff08;圆弧&#xff0…