当前位置: 首页 > article >正文

C语言(12) 指针的常见操作

指针的常见操作指针变量有两方面的意思:一个指针指向的内容(数据值一级)指针变量本身存储的数据 (地址值)#include stdio.h int main() { int a 10; int b 0 ; int c 50; int *p NULL; int *q NULL; p a; // 对指针变量本身进行修改 // 对指针指向的数据 进行操作 b *p ;// 通过地址获得地址中数据, 相当与是对 a变量的读取 *p 20;// 把需要写入的数据通过地址写入对应的内存 对a 变量的写入 p c; // p变量本身发生变化与c变量关联 b *p; // 对c变量读取操作 *p 10; //对 c变量的写入操作 q p;// 把p指向的地址赋值给q。pq 指向同一个变量了c。 return 0; }赋值运算符的左右值p做 左值 对指针变量本身进行修改 存储某个变量的地址p做 右值 把p指向的地址赋值给另外一个指针。p另一个 指向同一个变量了。*p做 左值 向指针指向的变量 写入数据*p做 右值 读出向指针指向的变量的数据指针作为参数 传参函数传递参数1. 值传递 在主调函数中实参在被调函数中形参。 形参可以读出实参的数据。但是不能修改实参的值。2.地址传递。 在主调函数中实参; 在被调函数中形参。 形参可以通过间接访问的方式读写实参的数据。实参和形参都是指针。这两个指针中存储的地址值同一个变量的地址。#include stdio.h int func(int a, int b, int* sum, int* sub) { *sum a b; *sub a - b; return 0; } int main(int argc, char** argv) { int a 10; int b 20; int sum 0; int sub 0; func(a, b, sum, sub); int *pa NULL; printf(a is %d b is %d sum:%d sub:%d\n, a, b, sum, sub); return 0; }函数使用指针作为参数1. 第一种情况需要形参修改实参的情况。需要被调函数修改主调函数中数据的值。2. 函数的返回值只有一个。 在被调函数中需要返回多个数据的话就需要传递值指针。因为在被调函数中可以修改主调函数的参数的只。void swap(int arg_a,int arg_b)//值传递 { int t arg_a; arg_a arg_b; arg_b t; } void swap2(int * pa,int *pb) //地址传递 { int t *pa; *pa *pb; *pb t; } int main() { int a 1; int b 2; //swap(a,b); swap2(a,b); printf(a is %d,b is %d\n,a,b); // 指针可以指向 任意0-4G地址 。但是不一定能读写内存有保护机制 int * p (int*)0x2000; }指针和数组的关系1. 数组名是一个指向数组第一元素的指针常量(指针本身的值不能发生变化。 指针是保存地址的变量指针保存的地址不能发生变化)。2. 数组名的类型 int a[] ; 类型 int [] int [ ] ≈ int * ;int [ ] ≈ int * ; c语言中兼容类型。大部分可以相互替换但是有例外。不同点1. sizeof()int* -- 8byte int a[20] - 20*sizeof(int) 80byte2. 在执行 取地址操作int*p - - int **(二级指针地址的地址)int a[10] - - int (*p)[10] (数组指针)int a[10] ; 对于数组名a 来说可以把他想成一个指针变量 。 本质 a 是数组中第一个元素地址的别名。一维数组做参数// int fill_array(int a[],int size) int fill_array(int *a, int size) { int i 0; // for(i0;isize;i) // { // a[i] rand()%50; // } for (i 0; i size; i) { //(*a)i rand()%50; *(a i) rand() % 50; } return 0; }一维字符数组做参数#include stdio.h //void show_str(char a[]) void show_str(char *a) { int i 0 ; // while(\0!a[i]) // { // printf(%c,a[i]); // i; // } // printf(\n); // while(\0!*(ai) ) // { // printf(%c,*(ai)); // i; // } // printf(\n); while(\0!*a) { printf(%c,*(a)); } printf(\n); } int main(int argc, char **argv) { char str[100]{0};// char [] -- char * printf(input str); gets(str); show_str(str); return 0; }字符指针常见错误#include stdio.h int main(int argc, char **argv) { //char *p hello; // hello 在内存中只用一份只能读取不能修改 char p[] hello; // char [] 开辟空间会把hello字符串常量复制一份给数组。 printf(%s\n, p); *(p 0) e; // 如果是指针操作是错误不能修改常量 p[0] e; // 如果是数组操作是对的修改的是数组里的内容不是字符串常量 printf(%s\n, p); return 0; }野指针#include stdio.h void swap(int *a,int *b) { int *t; // int t; *t *a; // t *a; // *t ,是野指针 *a *b; *b *t; } int main(int argc, char **argv) { int a 10; int b 20; swap(a,b); /* */ return 0; }函数指针指针函数1. 指针函数函数的返回值是 指针类型 。char *strcpy(char *dest, const char *src);strcpy 这个函数的返回值就是一个指针。 成功指针指向 dest。1 不能返回是局部作用域的指针。2 希望函数可以连续调用。 在同一个语句里面。 strcpy(str1,strcpy(str3,str2));3希望返回一端内存区域 (数组堆空间)。#include stdio.h #if 0 int * func1() // 错的 { int a[10]{1,2,3,4,5,6};// 0x2000 这个数组是个局部变量 printf(a addr %p\n,a[0]); return a;// a a[0] 不要返回局部变量 } int * func2() //对的 { static int a[10]{1,2,3,4,5,6};// 0x2000 printf(a addr %p\n,a[0]); return a;// a a[0] } int main(int argc, char **argv) { int *p NULL; p func2(); printf(main p addr %p\n,p); printf(p[0] %d\n,p[0]); return 0; } //............................. int * fun3(int *a,int size) { a[1]a[3]a[5]20; return a; } int main(int argc, char **argv) { int a[10]{0};// 0x2000 int * p fun3(a,10); printf( a[1]:%d a[3]:%d\n,a[1],a[3]); printf( p[1]:%d p[3]:%d\n,p[1],p[3]); return 0; }#include stdio.h #include string.h int mystrcpy(char *dst, char *src) { while (*src) { *dst *src; dst; src; } *dst\0; return 0; } char* mystrcpy2(char *dst, char *src) { char * tmp dst; while (*src) { *dst *src; dst; src; } *dst\0; return tmp; } char* mystrcat(char *dst,char * src) { char* tmp dst; while(*dst) { dst; } while(*src) { *dst*src; src; dst; } *dst \0; return tmp; } int main(int argc, char **argv) { char str1[100]hello; char str2[100]ok; char str3[100]{0}; // char *strcpy(char *dest, const char *src); //strcpy(str1,strcpy(str3,str2));// strcpy(str3,str2); str3 , strcpy(str1,str3); //printf(str1 is %s\n,str1); // mystrcpy2(str1,mystrcpy2(str3, str2)); // printf(str1 is %s\n,str1); mystrcat(str3,mystrcat(str1,str2)); printf(str3 is %s\n,str3); return 0; }2. 函数指针前面介绍的指针基本都是指数据。函数指针指向一个函数。本质指针变量函数名是地址值。里面储存的代码对数据进行加减乘除操作的。目的避免代码的重复。 方便后期代码的扩展。函数功能的解耦合。回调函数一个函数被当作参数 传递给另外一个函数。 被传递这个参数(函数指针回调函数)被动调用。主调函数只是传参(函数)语法 int add(int a, int b) // int (*) (int,int) { return a b; } int main(int argc, char **argv) { int (*p)(int, int) add; // p 函数指针。 add 不能写成add(), 不是对add函数的调用 int a 10; int b 20; int ret 0; ret add(a, b); printf(add() is %d\n, ret); ret p(a, b); // 通过函数指针 对函数的调用 printf(p() is %d\n, ret); return 0; }#include stdio.h #include stdlib.h #include time.h int fill_array(int *a, int size) { int i 0; // for(i0;isize;i) // { // a[i] rand()%50; // } for (i 0; i size; i) { //(*a)i rand()%50; *(a i) rand() % 50; } return 0; } int find_num3(int* a,int size) { for(size_t i0;isize;i) { if(0 a[i]%3) { printf(%d\n,a[i]); } } return 0; } int find_num5(int* a,int size) // int (*) (int*,int) { // int a; int ; int* p ;int* for(size_t i0;isize;i) { if(0 a[i]%5) { printf(%d\n,a[i]); } } return 0; } //............................................... int div3(int num) // div3 - int (*) (int) { return 0 num %3; } int div5(int num) // div3 - int (*) (int) { return 0 num %5; } void find_num(int* a,int size, int (*fun) (int) ) { for(size_t i0;isize;i) { if( fun(a[i])) // if( div5(a[i])) { printf(%d\n,a[i]); } } } int main(int argc, char **argv) { srand(time(NULL)); int a[10]{0}; fill_array(a,10); //find_num3(a,10); find_num(a,10,div5); // div5(); return 0; }typedef 关键字取别名 给数据类型取别名1. 普通数据类型 去别名typedef 老数据类型名 新数据类型名 typedef unsigned char u8; typedef unsigned short u16; typedef char s8; int main(int argc, char **argv) { u8 a; // unsigned char u16 b; // unsigned short s8 c; // char return 0; }2. 简化函数指针的写法typedef int* (*PFUN)(int ,int ,char* ); // int* func(int a,int b ,char* c) // int* (*)(int ,int ,char* ) // { // return NULL; // } // int func2(int a,int b, int* (*pfun)(int ,int ,char* )) // { // return 0; // } int* func(int a,int b ,char* c) // int* (*)(int ,int ,char* ) { return NULL; } int func2(int a,int b, PFUN pfun) { char str[]{0}; pfun(1,2,str); return 0; }3.和结构体有关晚些介绍

相关文章:

C语言(12) 指针的常见操作

指针的常见操作指针变量&#xff0c;有两方面的意思:一个指针指向的内容(数据值&#xff0c;一级)指针变量本身存储的数据 (地址值)#include <stdio.h>int main() {int a 10;int b 0 ;int c 50;int *p NULL;int *q NULL;p &a; // 对指针变量本身进行修改// 对指…...

想深耕网络安全行业,这些必备条件缺一不可

网络空间的攻防对抗日益激烈&#xff0c;网络安全已成为企业生存和国家安全的命脉&#xff0c;它负责构筑数字世界的坚固防线&#xff0c;保护核心资产与用户隐私免受侵害。 想要成为一名优秀的网络安全专家&#xff0c;除了敏锐的安全意识和高度的责任感&#xff0c;更需要锤…...

DeepSeek安全测试辅助Prompt工程白皮书(含17个CVE靶场验证指令模板)

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;DeepSeek安全测试辅助 DeepSeek系列大模型在代码生成、漏洞模式识别与安全上下文理解方面展现出独特优势&#xff0c;可作为安全测试工程师的智能协作者。其对OWASP Top 10、CWE分类体系及常见PoC结构具…...

3步快速上手Whisper-WebUI:轻松实现语音转字幕的完整指南

3步快速上手Whisper-WebUI&#xff1a;轻松实现语音转字幕的完整指南 【免费下载链接】Whisper-WebUI A Web UI for easy subtitle using whisper model. 项目地址: https://gitcode.com/gh_mirrors/wh/Whisper-WebUI 还在为视频制作繁琐的字幕而烦恼吗&#xff1f;Whis…...

第2章 谁在危险中——被AI替代的五类程序员

第2章 谁在危险中——被AI替代的五类程序员 核心问题:哪些程序员最容易被AI替代?背后的原因是什么? 2.1 问题定义:一场正在发生的结构性塌陷 2.1.1 数据不会说谎 2026年1月12日,Ravio发布了一份让整个科技圈沉默的报告:过去一年,初级开发者岗位招聘量暴跌73%。 不是…...

Cesium动态数据可视化实战:CallbackProperty结合setInterval打造实时运动轨迹

Cesium动态数据可视化实战&#xff1a;CallbackProperty结合setInterval打造实时运动轨迹 在三维地理信息系统中&#xff0c;实时数据可视化一直是开发者面临的挑战之一。想象一下&#xff0c;当我们需要在地球表面追踪一架正在飞行的无人机&#xff0c;或者监控城市中数百辆出…...

别让依赖毁了你的实验:记一次Vision Mamba复现中causal_conv1d与mamba-ssm的版本“打架”事件

Vision Mamba复现实战&#xff1a;破解依赖冲突的工程化解决方案在深度学习项目的复现过程中&#xff0c;依赖管理往往是最容易被忽视却又最常导致问题的环节。最近在复现Vision Mamba模型时&#xff0c;我遭遇了一场典型的Python依赖"战争"——causal_conv1d与mamba…...

别再乱建索引了!用Explain的key_len字段,一眼看穿你的MySQL联合索引到底生效了几个字段

解密MySQL联合索引&#xff1a;用key_len精准判断索引生效范围 在数据库性能优化领域&#xff0c;联合索引的使用一直是个既基础又容易踩坑的话题。很多开发者虽然知道"最左匹配原则"这个名词&#xff0c;但在实际业务场景中&#xff0c;面对复杂的查询条件组合时&a…...

终极指南:Windows 10完美安装PL2303驱动,解决老旧USB转串口芯片兼容性问题

终极指南&#xff1a;Windows 10完美安装PL2303驱动&#xff0c;解决老旧USB转串口芯片兼容性问题 【免费下载链接】pl2303-win10 Windows 10 driver for end-of-life PL-2303 chipsets. 项目地址: https://gitcode.com/gh_mirrors/pl/pl2303-win10 你是否还在为Windows…...

基于KS距离度量交通流分布偏移:提升DRL交通信号控制鲁棒性的工程实践

1. 项目概述与核心挑战在智能交通系统&#xff08;ITS&#xff09;领域&#xff0c;基于深度强化学习&#xff08;DRL&#xff09;的交通信号控制&#xff08;Traffic Signal Control&#xff09;正从研究走向实际部署。作为一名长期关注AI落地应用的从业者&#xff0c;我见过太…...

量子机器学习与傅里叶分析:革新期权定价的混合计算范式

1. 项目概述&#xff1a;当量子机器学习遇见金融定价在金融工程的核心地带&#xff0c;期权定价一直是个计算密集型的硬骨头。传统的蒙特卡洛模拟虽然通用&#xff0c;但为了达到足够的精度&#xff0c;动辄需要百万甚至千万次的路径模拟&#xff0c;计算成本高昂。近年来&…...

基于Arduino与蓝牙模块的六路无线开关控制系统设计与实现

1. 项目概述&#xff1a;用手机蓝牙控制六路LED想不想把手机变成一个无线遥控器&#xff0c;随手一点就能开关家里的灯带、氛围灯&#xff0c;甚至是其他电器&#xff1f;这个项目就是为你准备的。它基于一块功能增强的Arduino兼容板——GlowDuino Uno&#xff0c;配合一个极其…...

DIY智能USB充电器:基于电流检测与双稳态继电器的零功耗节能方案

1. 项目概述&#xff1a;打造一款智能、节能的USB手机充电器作为一名电子爱好者&#xff0c;我经常折腾各种电源项目。市面上很多手机充电器&#xff0c;包括一些原装货&#xff0c;都存在一个通病&#xff1a;手机充满电后&#xff0c;充电器依然插在插座上&#xff0c;内部电…...

基于PIC32单片机实现Android USB音频转SPDIF输出的DIY方案

1. 项目概述&#xff1a;为Android设备打造一个高保真SPDIF音频接口作为一名长期折腾嵌入式音频和家庭影院的玩家&#xff0c;我经常遇到一个痛点&#xff1a;手头那些性能不错的Android手机或平板&#xff0c;其内置的3.5mm耳机孔或者USB-C口的音频输出质量&#xff0c;在连接…...

微信红包助手终极指南:无需ROOT的智能抢红包解决方案

微信红包助手终极指南&#xff1a;无需ROOT的智能抢红包解决方案 【免费下载链接】WeChatLuckyMoney :money_with_wings: WeChats lucky money helper (微信抢红包插件) by Zhongyi Tong. An Android app that helps you snatch red packets in WeChat groups. 项目地址: ht…...

AutoPentest:面向红队的渗透测试决策引擎架构解析

1. 这不是又一个“自动化扫描器”&#xff0c;而是一套能替你做决策的渗透测试工作流引擎AutoPentest这个名字&#xff0c;第一眼容易让人联想到Nmap加个for循环、或者Burp Suite里点几下Intruder——但实际用过的人很快会意识到&#xff1a;它根本不在同一个维度上。我第一次在…...

中小企无需重型数据中台:轻量化数据体系搭建完整方案

过去几年&#xff0c;“数据中台”一度成为企业数字化的标配热词。大量中小企业盲目跟风搭建重型数据中台&#xff0c;投入高额成本、耗费数月甚至数年周期&#xff0c;最终落地效果极差&#xff1a;功能冗余、运维复杂、使用率低、投入产出比失衡。大量项目最终沦为“摆设式中…...

Burp抓包失败的五大隐形墙与HTTPS解密断裂点排查指南

1. 这不是Burp用得不对&#xff0c;是环境链路断在了你没看见的地方“Burp抓不到包”——这句话我过去三年里听开发、测试、刚转安全的新人说了不下两百遍。但真正打开Burp一看&#xff0c;Proxy标签页里空空如也&#xff0c;连个localhost:8080的请求都没有&#xff0c;十有八…...

5步彻底解决Windows DLL加载冲突:UE4SS系统故障排查指南

5步彻底解决Windows DLL加载冲突&#xff1a;UE4SS系统故障排查指南 【免费下载链接】RE-UE4SS Injectable LUA scripting system, SDK generator, live property editor and other dumping utilities for UE4/5 games 项目地址: https://gitcode.com/gh_mirrors/re/RE-UE4SS…...

Xia Sql插件:可调试的SQL注入决策引擎

1. 这不是又一个“自动扫SQL”的插件&#xff0c;而是把渗透工程师的判断逻辑塞进了Burp里你有没有过这种经历&#xff1a;在Burp Proxy里看着一堆GET参数、POST JSON、Cookie字段&#xff0c;心里清楚“这里大概率能注入”&#xff0c;但手动拼payload试了七八轮&#xff0c;还…...

ComfyUI-Manager完全指南:掌握AI工作流管理的核心技术

ComfyUI-Manager完全指南&#xff1a;掌握AI工作流管理的核心技术 【免费下载链接】ComfyUI-Manager ComfyUI-Manager is an extension designed to enhance the usability of ComfyUI. It offers management functions to install, remove, disable, and enable various custo…...

qobuz-dl终极实战指南:专业无损音乐下载工具架构解析与高效应用

qobuz-dl终极实战指南&#xff1a;专业无损音乐下载工具架构解析与高效应用 【免费下载链接】qobuz-dl A complete Lossless and Hi-Res music downloader for Qobuz 项目地址: https://gitcode.com/gh_mirrors/qo/qobuz-dl 在数字音乐时代&#xff0c;追求极致音质的音…...

Python strip 与 rstrip 函数区别

Python strip 与 rstrip 函数区别 文章目录Python strip 与 rstrip 函数区别一、核心作用二、基础语法三、基础使用示例四、指定删除特定字符五、常用业务场景一、核心作用 函数作用范围strip()移除字符串首尾空白字符rstrip()仅移除字符串右侧末尾字符&#xff0c;左侧保持不…...

【RT-DETR实战】070、模型分析工具:PyTorch Profiler性能分析

上周在部署RT-DETR到边缘设备时遇到一个诡异现象:模型推理时延波动极大,有时30ms,偶尔突然跳到200ms。 盯着代码看了半天没发现逻辑问题,数据流也正常。这种时候,靠猜是没用的,必须上性能分析工具——PyTorch Profiler。 今天我们就来聊聊怎么用它揪出那些藏在细节里的…...

在数据预处理与分析流水线中集成大模型API进行智能标注与摘要

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 在数据预处理与分析流水线中集成大模型API进行智能标注与摘要 对于数据工程师而言&#xff0c;处理海量非结构化文本数据是一项常见…...

Java网络编程基础分享

在学习 Java 的过程中&#xff0c;网络编程是非常重要的一环。无论是后端开发、分布式系统、即时通讯、文件传输&#xff0c;还是游戏服务、物联网设备&#xff0c;都离不开网络通信一、计算机网络基础1.1 什么是计算机网络把不同地理位置、具有独立功能的计算机&#xff0c;通…...

从无线破解到PDF解密:盘点那些容易被忽略的‘非主流’密码审计场景与工具

密码安全审计的隐秘战场&#xff1a;从无线网络到加密文档的实战指南 当大多数人谈论密码安全时&#xff0c;脑海中浮现的往往是服务器登录、数据库访问这些企业级场景。然而在数字生活的每个角落&#xff0c;从家庭Wi-Fi到工作文档&#xff0c;密码保护的脆弱性同样可能成为安…...

JS中forEach与普通for

for就不用说了&#xff0c;最普通的循环函数forEach1. 只写 1 个参数只接收当前遍历元素let arr [10,20,30] arr.forEach(item > {console.log(item) // 依次 10、20、30 })2. 写 2 个参数依次接收元素值、下标索引let arr [10,20,30] arr.forEach((item, index) > {co…...

国产麒麟系统上编译GDAL 3.2.1踩坑记:从PROJ6依赖缺失到Qt环境集成

麒麟系统GDAL 3.2.1编译实战&#xff1a;PROJ6依赖修复与Qt工程深度集成在国产操作系统生态中部署地理数据处理工具链&#xff0c;往往会遇到比常规Linux发行版更复杂的依赖问题。最近在麒麟系统上为北斗定位项目编译GDAL 3.2.1时&#xff0c;遭遇了经典的"PROJ 6 symbols…...

网安学习第24天 PHP安全——PHP反序列化

一、序列化与反序列化 1、序列化serialize() 序列化是什么&#xff1f;序列化就是把程序中的对象、数组、结构体等复杂数据&#xff0c;转换成可以存储或传输的格式。 简单说&#xff1a; 把“内存里的对象”变成“字符串/字节流”。 例如 PHP 中有一个对象&#xff1a; $u…...