c语言指针详解(上)

news2024/11/28 6:35:27

目录

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

二、指针运算

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/1286629.html

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

相关文章

Visual Studio Code tasks.json中控制任务执行问题面板显示内容的PresentationOptions介绍

☞ ░ 前往老猿Python博客 ░ https://blog.csdn.net/LaoYuanPython 一、引言 在 Visual Studio Code 中&#xff0c;tasks.json 文件用于配置和控制任务的执行&#xff0c;其中的 presentation配置项可以用来控制任务执行时在终端面板窗口中输出的内容&#xff0c;presentat…

单机无锁线程安全队列-Disruptor

Disruptor 1、基本介绍 说到队列&#xff0c;除了常见的mq中间件&#xff0c;java中也自带线程安全的BlockingQueue&#xff0c;但是BlockingQueue通过在入队和出队时加锁的方式避免并发操作&#xff0c;性能上会大打折扣。 而Disruptor是一个线程安全、低延迟、吞吐量高的队…

代替APP?微信小程序到底好在哪?

2019年是微信小程序宣布登场的一年&#xff0c;它实现了应用程序能被“垂手可得”的愿望。用户只需简单扫一扫或搜索&#xff0c;就能轻松打开应用。与需要在应用市场下载的APP相比&#xff0c;微信小程序可以在微信中被轻易地获取和传播&#xff0c;同时也带来了非凡的使用体验…

102.套接字-Socket网络编程4(TCP通信流程)

目录 TCP编程流程 套接字函数 1.创建套接字 2.绑定地址 3.监听连接请求 4.接受连接 5. 连接到服务器 6. 发送数据 7. 接收数据 8.关闭套接字 服务器端通信流程 示例代码 客户端通信流程 代码示例 TCP编程流程 TCP是一个面向连接的&#xff0c;安全的&#xff0c;流…

单调栈与单调队列算法总结

单调栈 知识概览 单调栈最常见的应用是找到每一个数离它最近的且比它小的数。单调栈考虑的方式和双指针类似&#xff0c;都是先想一下暴力做法是什么&#xff0c;然后再挖掘一些性质如单调性&#xff0c;最终可以把目光集中在比较少的状态中&#xff0c;从而达到降低时间复杂…

【Linux】基础IO--重定向理解Linux下一切皆文件缓冲区

文章目录 一、重定向1.什么是重定向2.dup2 系统调用3.理解输入重定向、输出重定向和追加重定向4.简易shell完整实现 二、理解linux下一切皆文件三、缓冲区1.为什么要有缓冲区2.缓冲区的刷新策略3.缓冲区的位置4.实现一个简易的C语言缓冲区5.内核缓冲区 一、重定向 1.什么是重定…

VMware虚拟机系统CentOS镜像的下载

文章目录 阿里云下载官网下载参考文档 一些小版本可能过时或者其他原因已经不能存在了&#xff0c;只有大版本号最新的&#xff0c;或者其他最新版本 阿里云下载 1-百度搜索&#xff1a;阿里云 2-找到开发者社区 3-找到下载&#xff0c;选择镜像 4-选择系统 5-点击镜像地…

【eNSP实践】eNSP实战篇(2)之简单实现交换机与主机的配置(图文详解)

目录 写在前面涉及知识1、交换机实验1.1 实验条件1.2 实验步骤A、打开eNSP软件&#xff0c;创建拓扑B、搭建主机与交换机连线C、配置交换机和主机D、验证不同网段设备可通性 1.3 通过交换机查看MAC地址 写在最后 写在前面 其实前面文章我有介绍关于路由器的使用&#xff0c;但…

OCP Java17 SE Developers 复习题08

答案 答案 答案 A. This code is correct. Line 8 creates a lambda expression that checks whether the age is less than 5, making option A correct. Since there is only one parameter and it does not specify a type, the parentheses around the parameter are …

TrustZone​之在安全状态之间切换

如果处理器处于NS.EL1,而软件想要转移到S.EL1,应该如何实现呢? 要改变安全状态,无论是向上还是向下,执行都必须经过EL3,如下图所示: 前面的图表显示了在不同安全状态之间移动涉及的步骤的示例序列。逐步进行解释: 进入较高的异常级别需要一个异常。通常,此异常…

网络程序设计

互相连接&#xff0c;发送信息 tcp和udp协议 tcp会有准备&#xff0c;udp不会准备。 8080端口&#xff1a;tomcat端口&#xff0c;java和web相连接 80端口&#xff1a;http 21端口&#xff1a;ftp 套接字 socket&#xff1a;提供给程序可以对外进行连接的接口 ip地址 特…

利用github copilot完成代码,利用正则化完成字符串中信息查找

利用正则化完成字符串中的字符拆解。 下面的代码是实现在“计算机组成原理-计科2101-123456-小明同学.docx”中提取出班级&#xff08;grade&#xff09;&#xff0c;学号&#xff08;id&#xff09;&#xff0c;姓名&#xff08;name&#xff09;。以下的代码都是github copi…

java中Random随机数使用和生成随机数的多个示例

在 Java 中&#xff0c;我们可以使用 java.util.Random 类生成伪随机数。伪随机数的特性是&#xff0c;虽然它们看起来是随机的&#xff0c;但实际上它们是由一个固定的算法生成的。只要我们提供相同的种子&#xff0c;这个算法就会生成相同的数字序列。 首先&#xff0c;我们…

Java链接数据库

本文介绍的是Java链接数据库中的JDBC操作&#xff0c;JDBC虽然现在用的不多&#xff0c;但面试的时候会问道。需要有相应的了解。下面以链接MySQL为例子。 JDBC 什么jdbc Java DataBase Connectivity是一种用于执行SQL语句的Java API&#xff0c;它由一组用Java语言编写的类和…

pod容器内无法访问集群外部主机ipv6地址

一、背景 同事反馈他这边有一环境出现pod容器内无法请求集群外部主机ipv6地址&#xff0c;但是在pod所在集群所主机上是可以请求到外部主机ipv6地址。 二、问题处理过程 首先主机和主机之间ipv6地址能通讯&#xff0c;说明主机之间网络是没啥问题&#xff0c;哪问题就出在容器…

Python语言基础学习大纲(由某大模型生成)

自从上次经丙察察游了一次滇藏线&#xff0c;已有3个没写一篇了。今天利用由某大模型生成的上面这张思维导图&#xff0c;配合这个大模型生成的6000多字拼凑出一篇博文聊以交差。 Python语言概述 一、语言特点 1.语法简单明了 Python的语法简洁易懂&#xff0c;使得编写代码…

邮件群发工具的功能:实用性与高效率功能推荐

市场营销对于每个企业来讲都至关重要&#xff0c;他能为企业带来商机的增长&#xff0c;获得持续的收益。邮件营销作为一种传统但是较少为众多行业使用的营销手段&#xff0c;同样也存在着无限的潜力。 它可以实现&#xff1a; 精准点对点个性化营销。数据报表追踪营销效果。…

如果不小心修改了按钮的名字并且忘记了原名字

出现上述情况&#xff0c;可以右边点击转到代码&#xff0c;注释掉问题行&#xff0c;此页的设计界面就恢复了。

Taro 学习教程 - - - - - 开发环境的安装 helloworld

一、Taro脚手架安装 npm install tarojs/cli -g // or yarn add tarojs/cli -g // or cnpm install tarojs/cli -g1.1 如何判断taro安装成功 taro -v正常安装成功之后显示如图&#xff1a; 1.2 环境变量配置(自行判断是否需要手动配置) 如果遇到如下问题&#xff0c;则是需要…

顶级资源!五个免费图标素材网站

图片太花哨了&#xff0c;纯文本太单调了&#xff1f;别忘了设计师的魔法武器——图标&#xff01;图标材料是UI设计师不可缺少的一部分。优秀的图标设计不仅可以提高界面美感&#xff0c;还可以提高用户的互动体验&#xff0c;帮助用户更好地了解应用程序的功能和信息。在本文…