C 深入指针(1)

目录

一、const

1、const修饰变量

2、const修饰指针

2.1 const int* p(int const* p)

2.2 int* const p

2.3 结论

二、指针运算

1、指针 +- 整数

2、指针 - 指针

3、指针的关系运算

三、指针的使用

1、模拟实现 strlen

2、传值调用和传址调用


一、const

1、const修饰变量

通过上图的报错信息可知,被const修饰的变量无法别修改,那我们试试通过地址修改他

#include<stdio.h>
int main()
{
	const int n = 10;
	int* p = &n;    
	*p = 20;
	printf("%d", n);    //成功输出20!
	return 0;
}

还真可以,这让我想到那些红客哈哈好厉害。

在这里我们明明不想n被改变,结果通过指针给n改了,这是不合理的!那该怎么办呢?


2、const修饰指针

2.1 const int* p(int const* p)

在 * 左边加上const可以看到,*p 无法被修改了

int const* p = &n;    //和 const int* p 等价

2.2 int* const p

那指针内的地址能修改吗

可以看到地址能被修改,指针变量 p 存放的本来是 n 的地址,输出应该是10,结果输出100;说明 p 存放的地址被改成了 m 的地址;地址不想被修改怎么办?

在 * 右边加上const可以看到,p 无法被修改了


2.3 结论

const 如果放在 * 的左边,修饰的是指针指向的内容,保证指针指向的内容不能通过指针来改变。 但是指针变量本身的内容可变。

const 如果放在 * 的右边,修饰的是指针变量本身,保证了指针变量的内容不能修改,但是指针指 向的内容,可以通过指针改变。  

如果都不想被修改,左右都加上const就好啦

const int* const p = &n;

int const* const p = &n


二、指针运算

指针的基本运算有三种,分别是:

  • 指针 +- 整数
  • 指针 - 指针
  • 指针的关系运算

1、指针 +- 整数

#include<stdio.h>
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int* p = arr;
	//依次打印数组内容
	for (int i = 0; i < 10; i++)
	{
		//printf("%d ", arr[i]);
		printf("%d ", *(p + i));	//指针+整数	
	}
	return 0;
}

2、指针 - 指针

#include<stdio.h>
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int* p1 = arr;		//指向数组第一个元素
	int* p2 = arr + 9;	//指向数组最后一个元素
	//输出的是字符串的长度,9
	printf("%zd", p2 - p1);
	return 0;
}

3、指针的关系运算

#include<stdio.h>
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int* p1 = arr;		//指向数组第一个元素
	int* p2 = arr + 9;	//指向数组最后一个元素
	//依次打印数组元素
	while (p1 <= p2)    //关系运算
	{
		printf("%d ", *p1);
		p1++;
	}
	return 0;
}

三、指针的使用

1、模拟实现 strlen

库函数strlen的功能是求字符串长度,统计的是字符串中 \0 之前的字符的个数。

#include<stdio.h>
#include<string.h>	//使用strlen时必须声明的头文件
int main()
{
	char arr[] = "abcd";
	size_t length = strlen(arr);
	printf("%zd", length);	//输出 4
	return 0;
}

通过使用指针来模拟实现 strlen函数:

#include<stdio.h>
int my_strlen(const char* p)
{
	int count = 0;
	while (*p)	//遍历到末尾的 \0 就会终止循环
	{
		count++;
		p++;
	}
	return count;
}
int main()
{
	char arr[] = "abcdef";
	int length = my_strlen(arr);	//模拟strlen
	printf("%d", length);
	return 0;
}

2、传值调用和传址调用

我们通过写一个交换值的函数来告诉这两者的区别

#include<stdio.h>
//传值调用
void swap(int x, int y)	//x = a; y = b
{
	int tmp = x;
	x = y;
	y = tmp;
}
int main()
{
	int a = 1;
	int b = 100;
	printf("交换前:a = %d b = %d\n", a, b);
	swap(a, b);	//想实现交换两个变量的值
	printf("交换后:a = %d b = %d", a, b);
	return 0;
}

运行之后发现 a 和 b 的值根本没有改变,这是为什么,启动调试监测

不清楚为什么是栈区可以看初阶 C语言的变量和算术操作符-CSDN博客

结论:实参传递给形参的时候,形参会单独创建一份临时空间来接收实参,对形参的修改不影响实 参。 所以 swap() 失败了。 

所以我们需要传址调用

#include<stdio.h>
//传址调用
void swap(int* x, int* y)	//x = &a; y = &b
{
	int tmp = *x;
	*x = *y;
	*y = tmp;
}
int main()
{
	int a = 1;
	int b = 100;
	printf("交换前:a = %d b = %d\n", a, b);
	swap(&a, &b);	//实现交换两个变量的值
	printf("交换后:a = %d b = %d", a, b);
	return 0;
}

这次就成功交换了,这里调用 swap函数 的时候是将变量的地址传递给了函数,这种函数调用方式叫:传址调用

传址调用,可以让函数和主调函数之间建立真正的联系,在函数内部可以修改 main函数 中的变量;所以未来函数中只是需要 main函数 中的变量值来实现计算,就可以采用传值调用。如果函数内部要修改 main函数 中的变量的值,就需要传址调用。


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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

安装VMware Tools报错处理(SP1)

一、添加共享文件 因为没有VMware Tools&#xff0c;所以补丁只能通过共享文件夹进行传输了。直接在虚拟机的浏览器下载的话&#xff0c;自带的IE浏览器太老了&#xff0c;网站打不开&#xff0c;共享文件夹会方便一点&#xff0c;大家也可以用自己的方法&#xff0c;能顺利上…

Kafka介绍、安装以及操作

Kafka消息中间件 1.Kafka介绍 1.1 What is Kafka&#xff1f; 官网&#xff1a; https://kafka.apache.org/超过 80% 的财富 100 强公司信任并使用 Kafka &#xff1b;Apache Kafka 是一个开源分布式事件流平台&#xff0c;被数千家公司用于高性能数据管道、流分析、数据集成…

kubernetes中使用ELK进行日志收集

目录 一、需要收集哪些日志 1、kubernetes集群的系统组件日志 2、应用日志 二、日志收集方案ELK 1、收集日志&#xff1a;Logstash 2、存储日志&#xff1a;Elasticsearch 3、展示日志&#xff1a;Kibana 三、安装elk 1、下载安装包 2、创建用户并切换到新用户 3、上…

【Excel】excel连接数字和符号

使用“&”对数字和符号进行连接 示例&#xff1a; 将“2.6”和“&#xff0c;”连成“2.6&#xff0c;” 连接公式为&#xff1a; V3&W3 V3和W3分别是"2.6"和“&#xff0c;”在excel中的位置

数据结构的队列(c语言版)

一.队列的概念 1.队列的定义 队列是一种常见的数据结构&#xff0c;它遵循先进先出的原则。类似于现实生活中排队的场景&#xff0c;最先进入队列的元素首先被处理&#xff0c;而最后进入队列的元素则要等到前面的元素都被处理完后才能被处理。 在队列中&#xff0c;元素只能…

Text-to-SQL小白入门(12)Awesome-Text2SQL开源项目star破1000

项目介绍 项目地址 23年9月份刚开源这个项目&#xff0c;大半年过去了&#xff0c;star数终于破1000啦&#xff0c;决定在知乎更新一下内容&#xff0c;看看内容变化&#xff0c;知乎有上当时项目介绍的链接&#xff1a;追光者&#xff1a;Text-to-SQL小白入门&#xff08;六&…

2.1 Java全栈开发前端+后端(全栈工程师进阶之路)-前端框架VUE3-基础-初识Vue

Vue概述 早期前后端分离模式 早期的前后端分离开发模式是这样的&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge">&l…

axios.get请求 重复键问题??

封装的接口方法&#xff1a; 数据&#xff1a; 多选框多选后 能得到对应的数组 但是请求的载荷却是这样的,导致会请求不到数据 departmentChecks 的格式看起来是一个数组&#xff0c;但是通常 HTTP 请求的查询参数不支持使用相同的键&#xff08;key&#xff09;名多次。如…

蓝桥杯练习系统(算法训练)ALGO-953 混合积

资源限制 内存限制&#xff1a;256.0MB C/C时间限制&#xff1a;1.0s Java时间限制&#xff1a;3.0s Python时间限制&#xff1a;5.0s 问题描述 众所周知&#xff0c;人人都在学习线性代数&#xff0c;既然都学过&#xff0c;那么解决本题应该很方便。   宇宙大战中&…

STM32 看门狗WDG

一、看门狗&#xff08;Watchdog&#xff09; 看门狗可以监控程序的运行状态&#xff0c;当程序因为设计漏洞、硬件故障、电磁干扰等原因&#xff0c;出现卡死或跑飞现象时&#xff0c;看门狗能及时复位程序&#xff0c;避免程序陷入长时间的罢工状态&#xff0c;保证系统的可靠…

BetterDisplay Pro for Mac:显示器校准软件

BetterDisplay Pro for Mac是一款出色的显示器校准软件&#xff0c;旨在提升你的视觉体验。它提供了准确的显示器参数调整&#xff0c;包括亮度、对比度、色温和色域等&#xff0c;让你的显示器呈现更真实、清晰、细腻的图像。此外&#xff0c;软件还提供多种预设模式和自定义选…

ABAP 数据写入Excel 并保存

参考老白 https://www.cnblogs.com/liaojunbo/archive/2011/09/06/2168552.html 但是缺zcl_excel 。需要从 dotabap要引入abap2xlsx 英文版进入后 尝试了一下 1&#xff09;列的宽度自适应么有找到在哪里&#xff1f; 列宽设置 lo_worksheet->set_column_width( ip_co…

基于springboot+vue+Mysql的网上商城购物系统

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

reactjs后台管理系统搭建

1 通过yarn 模板创建reactjs项目 yarn create vite reactjs-antdesign-admin --template react-ts 2 基础路由测试 定义一个router/index.tsx&#xff0c;里面定义路由组件 const Router: React.FC () > {return (<HashRouter><Switch><Route path"…

设计模式: 责任链模式

目录 一&#xff0c;责任链模式 二&#xff0c;特点 四&#xff0c;实现步骤 五&#xff0c;代码 一&#xff0c;责任链模式 责任链模式&#xff08;Chain of Responsibility Pattern&#xff09;是一种软件设计模式&#xff0c;它属于行为型模式。在这种模式中&#xff0c…

WPF之创建无外观控件

1&#xff0c;定义无外观控件。 定义默认样式&#xff0c;在其静态构造函数中调用DefaultStyleKeyProperty.OverrideMetadata()。 //设置默认样式DefaultStyleKeyProperty.OverrideMetadata(typeof(ColorPicker), new FrameworkPropertyMetadata(typeof(ColorPicker))); 在项目…

tomcat篇-windows 运行tomcat的startup.bat时,终端打印的中文显示为乱码

当运行Tomcat的startup.bat时&#xff0c;如果终端中中文显示为乱码&#xff0c;这通常是因为Tomcat使用的日志输出编码与Windows命令行默认的编码不匹配。针对这一问题&#xff0c;你可以尝试以下步骤来解决&#xff1a; 1、执行startup.bat&#xff0c;在输出的窗口右击&…

Android --- 网络请求

通常在 Android 中进行网络连接一般使用 Scoket 和HTTP&#xff0c;HTTP 请求方式比 Scoket 多。HTTP 请求一般采用原生的 HttpClient 和 HttpUrlConnection 的两种网络访问方式&#xff08;系统自带的&#xff09;。但是在 Android 5.0 的时候 Google 就不推荐使用 HttpClient…

【限免】雷达目标生成与探测研究项目【附MATLAB代码】

文章来源&#xff1a;微信公众号&#xff1a;EW Frontier 课题背景 该项目的目标是模拟FMCW雷达检测运动目标&#xff0c;然后执行信号处理功能&#xff0c;以估计模拟目标的距离和多普勒速度。 图1&#xff1a;雷达模拟和检测的项目工作流程 FMCW波形设计 根据系统要求设计…

JAVA Coding 规范

Coding 规范 文章目录 Coding 规范一.文件规范1.1 声明1.2 缩进1.3 空行1.4 空格1.5 对齐1.6 小括号1.7 花括号1.8 代码长度 二.命名规范2.1 命名总则2.2 命名空间2.3 类与接口2.4 方法命名2.5 属性命名2.6 常量命名2.7 变量命名 三.语句规范3.1 语句总则3.2 循环语句3.3 Switc…