main函数,常量指针与指针常量,野指针等,void与void的区别

指针(续)

main函数原型

定义

main函数有多种定义格式,main函数也是函数,函数相关的结论对main函数也有效。

main函数的完整写法:

 int main(int argc, char *argv[]){..}int main(int argc, char **argv){..}

扩展写法:

 main(){}  等价 int main(){}   // C11之后不再支持 缺省 返回类型int main(void){}   等价 int main(){}void main(void){}  等价 void main(){}int main(int a){}int main(int a, int b, int c){}...

说明

① argc,argv是形参,他们俩可以修改

② main函数的扩展写法有些编译器不支持,编译报警告

③ argc和argv的常规写法

  • argc:存储了参数的个数,默认是1个,也就是运行程序的名字
  • argv:存储了所有参数的字符串形式

④ main函数是系统通过函数指针的回调调用。

演示

代码:

#include <stdio.h>int main(int argc, char **argv)  // {"abc","aaa"}   对行地址解引用,得到首列地址
{// 访问参数个数 argcprintf("argc=%d\n", argc);// 遍历参数(每一个参数都是一个字符串常量)for(int i=0;i< argc; i++){printf("%s,%s\n", argv[i], *(argv+i));}printf("\n");
}

运行结果:

在这里插入图片描述

在这里插入图片描述

常量指针与指针常量

常量类型

① 字面量:直接使用固定值(如:12,hello,orange, 杨家辉三角),符号常量和枚举在编译器转换为了字面量

② 只读常量:用const修饰的变量,初始化之后不可修改。

const int a = 10;  // 只读常量
a = 21;  // 编译报错

常量指针

  • 本质:指向常量数据的指针

  • 语法:

    const 数据类型 *变量名;
    const 数据类型* 变量名;
    
  • 举例:

    const int *p;   // p是常量指针
    
  • 特性:

    • 指向对象的数据不可改变(int a = 10; const int *p = &a; *p = 20;,非法)
    • 指针本身的指向可以改变(int a = 10, b = 20; const int *p = &a; p = &b;,合法)
  • 案例:

    #include <stdio.h>int main()
    {int a = 10;        // 变量const int *p = &a; // 常量指针// *p = 100;       // 错误,指针指向的数据不可改变printf("%d\n", *p);// 10int b = 20;        // 变量p = &b;            // 正确,指针指向可以改变printf("%d\n", *p);// 20
    }
    

指针常量

  • 本质:指针本身是常量,指向固定地址

  • 语法:

    数据类型* const 变量名;
    数据类型 *const 变量名;
    
  • 特性:

    • 指向对象的数据可以改变(int a = 10; int* const p = &a; *p = 20;,合法)
    • 指针本身的指向不可改变(int a = 10, b = 20; int* const p = &a; p = &b;,非法)
  • 注意:

    定义时必须初始化:

    int a = 10;
    int* const p = &a;  // 正确
    
  • 案例:

    #include <stdio.h>int main()
    {int a = 10;        // 变量int* const p = &a; // 指针常量*p = 100;          // 正确,指针指向的数据可以改变printf("%d\n", *p);// 100int b = 20;        // 变量// p = &b;            // 错误,指针指向不可改变printf("%d\n", *p);// 100
    }
    

常量指针常量

  • 本质:指针指向和指向对象的数据都不可改变

  • 语法:

    const 数据类型* const 变量名;
    const 数据类型 *const 变量名;
    
  • 举例:

    const int* const p;  // p是常量指针常量
    
  • 特性:

    • 指向对象的数据不可改变(int a = 10; int* const p = &a; *p = 20;,非法)
    • 指针本身的指向不可改变(int a = 10, b = 20; int* const p = &a; p = &b;,非法)
  • 注意:

    定义时需要初始化:

    int a = 10;
    const int *const p = &a; // 正确
    

    简单理解:不管是常量指针、指针常量还是常量指针常量,本质上都是一个赋值受到限制的指针变量。

总结对比

类型语法指向可变数据可变
常量指针const int *p✔️
指针常量int *const p✔️
常量指针常量const int *const p

关键点

  1. const* 左侧:修饰数据(常量指针)
  2. const* 右侧:修饰指针(指针常量)
  3. 函数参数优先使用常量指针,提高代码安全性
  4. 指针常量必须初始化,且不可重新指向

野指针、空指针、空悬指针

野指针

定义

指向无效内存区域(比如未初始化、已释放或者越界访问)的指针称之为野指针。野指针会导致未定义(UB)行为。

危害:

  • 访问野指针可能引发段错误(Segmentation Fault)
  • 可能破坏关键内存数据,导致程序崩溃。

产生场景:

  1. 指针变量未初始化

    int *p;    // p未初始化,是野指针
    printf("%d\n", *p); // 危险操作:p就是野指针
    
  2. 指针指向已释放的内存

    int *p = malloc(sizeof(int)); // 在堆区申请1个int大小的内存空间,将该空间地址赋值给指针变量p
    free(p); // 释放指针p指向的空间内存
    printf("%d\n", *p); // 危险操作:p就是野指针
    
  3. 返回局部变量的地址

    int* fun(int a, int b)
    {int sum = a + b; // sum就是一个局部变量return &sum;  // 将局部变量的地址返回给主调函数
    }int main()
    {int *p = fun(2,3);printf("%d\n", *p); // 危险操作:p就是野指针
    }
    

如何避免野指针:

  1. 初始化指针为NULL

  2. 释放内存后立即置指针为NULL

  3. 避免返回局部变量的地址

  4. 使用前检查指针有效性(非空校验,边界检查)。

    int fun(int *pt)
    {int *p = pt;// 校验指针if(p == NULL) // 结果为假   等价于 if(!p)  其实底层: if(p == 0){printf("错误!");return -1;}printf("%d\n", *p);return 0;
    }
    

空指针

**定义:**值为NULL的指针,指向地址0x000000000000(系统保留,不可访问)

**作用:**明确表示指针当前不指向有效内存,一般用作指针的初始化。

示例:

int *p = NULL;  // 初始化为空指针free(p);   // 释放后置空
p = NULL;

空悬指针

**定义:**指针指向的内存已经被释放,但未重新赋值。空悬指针是野指针的一种特例。

示例:

char *p = malloc(100); // 在堆区分配100个char的空间给p
free(p); // 释放指针p指向的内存空间
printf("%p,%d\n", p, *p); // p可以正常输出,*p此时属于危险操作 
// p指向的内存空间被回收,但是p指向空间的地址依然保留,此时这个指针被称作空悬指针

void与void*的区别

定义

  • void: 表示“无类型/空类型”,用于函数返回类型或者参数。

    void func(void);    // 没有返回值也没有参数,一般简写:void func();
    
  • *void:**通用指针类型(万能指针),可指向任意类型数据,但需要强制类型转换后才能解引用。

    void* ptr = malloc(4);  // ptr指向4个字节大小的堆内存空间  
    // 存放int类型数据
    int *p = (int*)ptr;
    *p = 10;// 存放float类型数据
    float* p1 = (float*)ptr;
    *p = 12.5f;// 存放char类型数组
    char* p2 = (char*)ptr;// 以下写法完全错误
    float* ptr = malloc(4);
    int *p = (int*)ptr;  // 此时编译报错,类型不兼容 float* int*
    

    注意:只能是具体的类型(int*,double*,float*,char*...)和void*之间转换

注意事项

  • void不能直接解引用(*ptr 会报错
  • 函数返回void*需要外部接收的时候明确类型(不明确类型,就无法解引用)

示例

#include <stdio.h>/*** 定义一个返回类型为void*类型的指针函数*/
void* proces_data(void* p)
{return p;
}int main(int argc, char *argv[])
{// int类型int m = 10;int* p_int = &m;int* result_int = (int*)proces_data(p_int);printf("Integer value:%d\n", *result_int);// double类型double pi = 3.1415926;double* p_double = &pi;double* result_double = (double*)proces_data(p_double);printf("Double value:%lf\n", *result_double);// void* p_void = proces_data(p_double);// printf("Void value:%lf\n", *p_void);// *p_void = 20;// 注意:void* 修饰的指针是可以进行赋值操作的,但是不能对其解引用return 0;
}

运行结果:

在这里插入图片描述

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

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

相关文章

Mac m系列芯片安装node14版本使用nvm + Rosetta 2

由于苹果 M 系列芯片&#xff08;包括 M4&#xff09;使用的是 ARM 架构&#xff0c;而 Node.js 14 是在英特尔 x86 架构时代发布的&#xff0c;因此在 M 系列 Mac 上安装 Node.js 14 可能会遇到兼容性问题 解决方法&#xff1a;使用 nvm Rosetta 2右键点击「终端」→「显示简…

前端基础之《Vue(26)—Vue3两种语法范式》

一、选项式1、HTML写法<!-- 跟 Vue 说 Hello World&#xff01; --><script type"module"> import { createApp } from vuecreateApp({data() {return {message: Hello World!}} }).mount(#app) </script><div id"app"><h1>…

题目:BUUCTF之rip(pwn)

网址 BUUCTF在线评测https://buuoj.cn/challenges#rip打开&#xff0c;如图所示 提示&#xff1a;先别启动靶机&#xff0c;靶机可以最后在启动&#xff0c;先分析下载的附件pwn1。 点击下载&#xff0c;下载完成之后&#xff0c;该文件后缀类型改为exe&#xff08;就是将pwn…

el-button长按触发事件(含未响应的解决方案)

参考代码实现按钮长按触发逻辑 <template><el-button mousedown"handleMouseDown" mouseup"handleMouseUp">长按我</el-button> </template>data(){return{isPressed: false,timer: null,}},methods:{handleMouseDown() {this.isP…

List和 ObservableCollection 的区别

1. 变更通知机制​​ ​​ObservableCollection<T>​​ 实现了INotifyCollectionChanged和INotifyPropertyChanged接口&#xff0c;当集合元素被添加、删除、替换或重置时&#xff0c;会自动触发CollectionChanged事件&#xff0c;通知绑定的UI控件更新&#xff08;如WPF…

支付宝沙箱(白屏,用户订单参数错误等)

情况&#xff1a;Laravel项目的line 对接 支付宝沙箱测试 手机网站支付 1&#xff1a;沙箱地址&#xff0c;小到我找不到&#xff1a;沙箱应用 - 开放平台 2&#xff1a;虽然提供了系统密钥&#xff0c;但是只是测API链接的&#xff0c;要沙箱测试转账什么的&#xff0c;得用…

【NLP舆情分析】基于python微博舆情分析可视化系统(flask+pandas+echarts) 视频教程 - 微博评论IP地图可视化分析实现

大家好&#xff0c;我是java1234_小锋老师&#xff0c;最近写了一套【NLP舆情分析】基于python微博舆情分析可视化系统(flaskpandasecharts)视频教程&#xff0c;持续更新中&#xff0c;计划月底更新完&#xff0c;感谢支持。今天讲解微博评论IP地图可视化分析实现 视频在线地…

【代码随想录】刷题笔记——二叉树篇

目录 144. 二叉树的前序遍历 94. 二叉树的中序遍历 145. 二叉树的后序遍历 102. 二叉树的层序遍历 226. 翻转二叉树 101. 对称二叉树 104. 二叉树的最大深度 111. 二叉树的最小深度 222. 完全二叉树的节点个数 110. 平衡二叉树 257. 二叉树的所有路径 404. 左叶子之…

基于deepseek的文本解析 - 超长文本的md结构化

pdf超长合同或其他超100页非结构化文档&#xff0c;很难全量提交deepseek进行分析&#xff0c;一般需要先进行分割。然而&#xff0c;不管是langchain还是llamaindex提供的文本分割工具&#xff0c;很难直接对非结构化文本进行准确的内容分割&#xff0c;很多原始整体段落被划分…

介绍一个图像修复开源项目,从模糊到清晰仅需1.7秒:HYPIR图像修复技术如何改变数字世界?

文章概要 作为一名长期关注图像处理技术的爱好者&#xff0c;当我第一次接触到HYPIR这一革命性图像修复工具时&#xff0c;我被其惊人的速度和质量所震撼。本文将全面介绍由中国科学院深圳先进技术研究院董超研究员团队研发的HYPIR图像修复大模型&#xff0c;详细解析其核心技术…

基于UDP的SNMP协议

SNMP协议详解 SNMP (Simple Network Management Protocol)&#xff0c;“简单网络管理协议”&#xff0c;是广泛应用于TCP/IP网络中&#xff0c;用于管理和监控网络设备的一种标准协议。它允许网络管理员查询网络设备的状态信息、配置参数、接收故障告警等&#xff0c;从而实现…

3D空间中的变换矩阵

3D 空间中的变换矩阵详解 在 3D 计算机图形学中&#xff0c;所有几何变换都可以通过 44 齐次变换矩阵 来表示。以下详细介绍各种变换矩阵及其原理。 核心变换矩阵 1. 单位矩阵&#xff08;不变变换&#xff09; I[1000010000100001] I \begin{bmatrix} 1 & 0 & 0 &…

长连接(Long Connection)详解

一、长连接基本概念长连接&#xff08;也称为持久连接&#xff09;是指在一个TCP连接上可以连续发送多个HTTP请求/响应&#xff0c;而不是每次通信都建立新的连接。这是HTTP/1.1的默认行为&#xff0c;通过Connection: keep-alive头部实现。二、工作原理1. 传统短连接流程客户端…

【汇总】接口自动化测试 + 持续集成(文末视频演示)

技术栈&#xff1a;java testng httpclient allure fastjson jsonpath poi/yaml log4j 有建议请联系wx&#xff1a;ren168632201 java接口自动化系列(01)&#xff1a;自动化测试框架设计(入门版) java接口自动化系列(02)&#xff1a;测试数据文件设计(excel/yam) java接…

科研快报 |无人机+AI:广东防控基孔热背后的技术革命

Prism Path 科 研 快 报 CS跨学科顶尖期刊论文资讯 -NO.2025001- 人工智能在登革热预防、控制与管理中的作用&#xff1a;一项技术性叙述综述 The role of artificial intelligence for dengue prevention, control, and management: A technical narrative review 期刊…

常见的中间件漏洞

建议&#xff1a;启动下一个环境时&#xff0c;将上一个环境关闭&#xff0c;防止端口冲突和运行卡顿1.TomcatTomcat put方法任意文件写入漏洞Apache Tomcat 7.0.0 - 7.0.79 Apache Tomcat 8.5.19环境&#xff1a;cd vulhub-master/tomcat/CVE-2017-12615 docker-compose up -d…

7寸工业模组 XA070Y2-L01芯显科技详细参数资料

芯显7寸工业液晶屏 XA070Y2-L01 技术规格单 基础信息 项目 参数 制造商 芯显 型号 XA070Y2-L01 显示技术 a-Si TN TFT-LCD 应用场景 车载中控 / 工业HMI 屏幕尺寸 7.0英寸 机械结构 特性 指标 显示区域 152.4 91.44 mm 整机尺寸 165 104.09 9.1 mm 公差范围 0.5 mm 表面处理…

机器学习基础-numpy

一、相关知识点二、例子&#xff1a;import matplotlib.pyplot as plt import numpy as npplt.rcParams[font.sans-serif] [KaiTi] # 使用黑体 plt.rcParams[axes.unicode_minus] False # 解决负号显示问题math np.random.randint(low60,high100,size50) english np.rand…

Cockpit管理服务器

Cockpit 是一个开源工具&#xff0c;通过Web Console管理Linux服务器。部署 Cockpit[rootserver ~ 11:05:26]# yum -y install cockpit​[rootserver ~ 11:30:26]# systemctl enable cockpit.socket --nowCreated symlink from /etc/systemd/system/sockets.target.wants/cockp…

处理订单过期但支付成功的系统设计:平衡用户体验与业务规则

设计一个处理订单过期但用户支付成功的场景&#xff0c;需要平衡用户体验、系统一致性和业务规则。以下是一个系统化的设计方案&#xff0c;涵盖关键流程、异常处理和用户沟通&#xff1a;1. 场景分析 背景&#xff1a;用户在下单后&#xff0c;订单因超时而被标记为“过期”&a…