C语言之指针

目录

函数的参数

对象和地址

取地址运算符

注意

指针

注意

指针运算符

注意


在C语言中,指针是一个十分重要的概念,它的作用是“指示对象”。

例如:你要去一座公寓楼找一位朋友,公寓楼由很多楼层组成,每个楼层由若干个房间组成,而房间都有属于一个自己的编号,假如你不知对应的楼层的房间号,你需要一个一个房间去找,这是很麻烦的,而当你指定对应的房号时就能快速精准定位目标,而这里的房间号就对应为地址,也可以称为指针。


下面我们由一个例子来引出接下来我们所要学习的关于指针的基本知识:

函数的参数

#include<stdio.h>

/*将n1和n2的和、差分别保存在sum、diff中(错误的示范)*/
void sum_diff(int n1, int n2, int sum, int diff)
{
	sum = n1 + n2;
	diff = (n1 - n2) ? n1 - n1:n2 - n1;
}
int main()
{
	int na, nb;
	int wa = 0, sa = 0;
	
	puts("请输入两个整数:");
	printf("整数A:");scanf("%d", &na);
	printf("整数B:");scanf("%d", &nb);

	sum_diff(na, nb, wa, sa);
	
	printf("两数之和是%d,两数之差是%d", wa, sa);
	
	return 0;
}

main函数在调用sum_diff函数时,实参na,nb,wa,sa的值会分别传递给形参n1,n2,sum,diff。这个复制的过程是单向的,这中参数传递方式称为值传递,这样即使改变形参sum,diff的值原来的wa,sa的值并不会改变。

因此在调用sum_diff函数之后,在main函数中wa,sa的值依然是0.

在前面的学习中,我们可以得知,函数返回到调用源的返回值只能有1个,不能返回到两个以上的值,所以不能将和、差返回给函数。

为了解决这个问题,必须掌握C语言学习的难点之一——指针(pointer)


对象和地址

变量是“保存数值的盒子”,它并不是像下图中随意存放的:

而是下面这样有序的存放在内存空间里:

变量具有多个侧面或者是属性,举例来说,其中一个属性就是数据类型长度,上面中的int型和double型的数据长度就不同,这两个变量的长度可以通过sizeof()求得。

有些编译器中sizeof(int)、sizeof(double)是相等的,但是构成它们的每一位却不尽相同

 数据类型决定变量可以表示数值范围,除此之外,表示变量在内存中生命期范围的存储期以及变量名也都是变量的重要属性。

在广阔的内存空间上,存在着很多对象,这就需要某种方式来表示各个对象在内存中存储的位置,这就是地址(address)

对象(变量)的地址是指其在内存中的存储编号,其中int型变量n的地址为212,double型变量x的地址为216。


取地址运算符

每个对象都有地址,那么我们来看下它们的地址是怎样的:

#include<stdio.h>

int main()
{
	int    n;
	double x;
	int  a[3];
    printf("n的地址:%p\n", &n);      
	printf("x的地址:%p\n", &x);
	printf("a[0]的地址:%p\n", &a[0]);
	printf("a[1]的地址:%p\n", &a[1]);
	printf("a[2]的地址:%p\n", &a[2]);

	return 0;
}
/*n的地址:0061FECC
x的地址:0061FEC0
a[0]的地址:0061FEB4
a[1]的地址:0061FEB8
a[2]的地址:0061FEBC*/

对象的地址通常都是由十六进制数表示的,但是在不同的编译器下,有时结果也不相同。

我们一直使用的单目运算符&通常被称为取地址运算符(address operator),将&写在对象名之前就可以得到该对象的地址。

如果对象的长度为2,占用212号和213号的内存单元,那么该对象的地址就是它的首地址212号。

取地址运算符
  &a                                                       取得a的地址(生成指向a的指针)

注意

取地址运算符&的功能是取得对象的地址,表示对象地址的转换说明为%p(p为pointer的首字母)。


指针

只显示地址并无意思,让我来看看更具实际作用的功能吧:

#include<stdio.h>

int main()
{
	int Lihua = 178;//李华的身高
	int Wangjun = 175;//王军的身高
	int Xiaoming = 179;//小明的身高
	
	int *honghong, *huahua;//红红、花花
	
	honghong = &Lihua;//honghong指向Lihua(喜欢李华)
	huahua = &Xiaoming;//huahua指向Xiaoming
	
	printf("红红喜欢的人身高:%d\n", *honghong);
	printf("花花喜欢的人身高:%d\n", *huahua);

	honghong = &Wangjun;//honghong指向Wangjun(移情别恋)
	
	*huahua = 180;//将huahua指向的对象赋值为180(修改花花喜欢的人身高)
	
	putchar('\n');
	printf("李华的身高是:%d\n", Lihua );
	printf("王军的身高是:%d\n", Wangjun );
	printf("小明的身高是:%d\n", Xiaoming );
	printf("红红喜欢的人的身高是:%d\n", *honghong);
	printf("花花喜欢的人的身高是:%d\n", *huahua);
	
	return 0;
}

变量honghong和huahua的声明中,变量名前带有 * ,通过该声明定义了两个“指向int型变量的指针变量”,它们指向的是int型对象

我首先明确一下“int型变量”和“指向int型变量的指针变量”有何区别:

☛int型变量:保存“整数”盒子

☛指向int型变量的指针变量:保存“存放整数对象的地址”的盒子

我们以下图为例:

int型Lihua的地址是212号,因此若执行“honghong = &Lihua”,honghong中就会被存入212号,这是honghong和Lihua的关系就是honghong指向lihua

当指针p的值为对象x的地址时,一般说“p”指向“x”。

honghong的数据类型是“指向int型变量的指针型”

honghong = &Lihua;

&Lihua的类型也是“指向int型变量的指针”,取地址运算符与其说时取得地址,不如说是生成指针。

表达式&Lihua是指向Lihua的指针,其值为Lihua的地址。

注意

将取地址运算符&写在Type型对象x前得到的&x为Type *指针,其值为x的地址。


指针运算符

在进行显示的地方,就要用到指针运算符(也称为间接访问运算符)的单目运算符 * (unary operator)。将指针运算符*写于指针之前,就可以显示该指针指向的对象内容。

指针运算符
*a                                          a指向的对象
#include<stdio.h>

int main()
{
	int a = 10;
	int *pa = &a; 
	*pa = 20;	
	
	printf("%d", a);
	return 0;
}

在这里*pa就存放变量a的地址,就相当于“pa指向的对象”,因此*pa就是变量a的别名,所以改动*pa存放地址的值,也就相当于改动了a的值。

注意

当pa指向a时,*pa就是变量a的别名。


指针在C语言中是十分重要的,但是不难理解:指针就相当于一个门牌号方便与从内存单元中查找,而形如int *a;的形式 *a指的是指针型变量,而加上int就是创造了一个保存对象地址的变量,而取得地址的指针型变量就相当于该地址所在变量的分身。

相信大家只要用心梳理几遍就可以明了了。在下面的学习中我们还将会学习关于函数、数组与指针的关系。

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

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

相关文章

解决 MATLAB 遗传算法中 exitflg=4 的问题

一、优化问题简介 以求解下述优化问题为例&#xff1a; P 1 : min ⁡ p ∑ k 1 K p k s . t . { ∑ k 1 K R k r e q l o g ( 1 α k ∗ p k ) ≤ B b s , ∀ k ∈ K p k ≥ 0 , ∀ k ∈ K \begin{align} {P_1:}&\mathop{\min}_{\bm{p}}{ \sum\limits_{k1}^K p_k } \no…

【Linux笔记】文件查看和编辑

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;Linux学习 ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 命令 cat (Concatenate and Display): more 和 less: nano 和 vim (文本编辑器): 结语 我的其他博客 前言 学习Linux命令行和文件…

1854_bash中利用管道进行批量参数传递以及由此实现简单的代码行数统计

Grey 全部学习内容汇总&#xff1a; GreyZhang/bash_basic: my learning note about bash shell. (github.com) 1854_bash中的参数传递以及利用bash进行简单的代码行数统计 有时候需要处理多个文件&#xff0c;把每一个文件作为参数传递给某一个程序。这时候可以用到 xargs&…

高频知识汇总 | 【操作系统】面试题汇总(万字长博通俗易懂)

前言 这篇我亲手整理的【操作系统】资料&#xff0c;融入了我个人的理解。当初我在研习八股文时&#xff0c;深感复习时的困扰&#xff0c;网上资料虽多&#xff0c;却过于繁杂&#xff0c;有的甚至冗余。例如&#xff0c;文件管理这部分&#xff0c;在实际面试中很少涉及&…

Ai图片处理

Ai也可以直接导入PS文件&#xff0c;只不过需要进行一个相关的选择&#xff0c;一般来说是将图层转化为对象 第二个为图层拼合为单个图像&#xff08;不常用&#xff09; 第三个则是将隐藏的图片也进行显示 如果你觉得图片的信息的过少好想插入其他的图片&#xff0c;可以选择…

认识Linux背景

1.发展史 Linux从哪里来&#xff1f;它是怎么发展的&#xff1f;在这里简要介绍Linux的发展史 要说Linux&#xff0c;还得从UNIX说起 UNIX发展的历史 1968年&#xff0c;一些来自通用电器公司、贝尔实验室和麻省理工学院的研究人员开发了一个名叫Multics的特殊操作系统。Mu…

BDD - Python Behave Tags 过滤

BDD - Python Behave Tags 过滤 引言实例创建 feature 文件创建 step 实现 Tag 过滤执行执行单个标签 --tagstagname执行多个标签 OR 关系 --tagstag1,tag2多个标签 AND 关系 --tagstag1 --tagstag2单标签非关系 --tags ~tagname 引言 随着项目进展&#xff0c;QA 创建的 Beh…

【JMeter】使用BeanShell写入内容到文件

一、前言 ​ 在我们日常工作中&#xff0c;可能会遇到需要将请求返回的数据写入到文件中。在我们使用JMeter进行性能测试时&#xff0c;就经常能够遇到这种情况。要想达到这种目的&#xff0c;我们一般采取BeanShell后置处理器来将内容写入到文件。 二、提取 ​ 在目前大多数的…

记一次 Nginx 调参的踩坑经历

最近在基于SSE&#xff08;Server Sent Events&#xff09;做服务端单向推送服务&#xff0c;本地开发时一切顺利&#xff0c;但是在部署到预发环境时就碰到1个很诡异的问题&#xff0c;这里需要简单介绍下我们的整体架构&#xff1a; 整体架构 可以看到所有的请求都会先到统一…

2. 结构型模式 - 桥接模式

亦称&#xff1a; Bridge 意图 桥接模式是一种结构型设计模式&#xff0c; 可将一个大类或一系列紧密相关的类拆分为抽象和实现两个独立的层次结构&#xff0c; 从而能在开发时分别使用 问题 抽象&#xff1f; 实现&#xff1f; 听上去挺吓人&#xff1f; 让我们慢慢来&#x…

2023年软件测试已经崩盘了吗?为什么很难找到工作?

最近后台很多粉丝给我留言&#xff1a; 2023年软件测试已经崩盘了吗&#xff0c;为什么都找不到工作了&#xff1f; 确实&#xff0c;今年经济大环境不好&#xff0c;企业也都在降本增效&#xff0c;如果技术能力还在被应届生竞争岗位的阶段&#xff0c;只会越来越难。 找不…

3d max高质量渲染时,硬件的要求有什么?

渲染过程中&#xff0c;想要追求&#xff0c;效果图高质量渲染&#xff0c;高效率渲染的过程中&#xff0c;3d max高清渲染不只是三维软件的一个要求&#xff0c;对于本地计算机的硬件要求配置也是很重要的。 今天&#xff0c;小编带大家来聊聊3d max高质量渲染过程中&#xff…

20 Vue3中使用v-for遍历普通数组

概述 使用v-for遍历普通数组在真实开发中还是比较常见的。 基本用法 我们创建src/components/Demo20.vue&#xff0c;代码如下&#xff1a; <script setup> const tags ["JavaScript", "Vue3", "前端"] </script> <template…

单例模式实现

⭐ 作者&#xff1a;小胡_不糊涂 &#x1f331; 作者主页&#xff1a;小胡_不糊涂的个人主页 &#x1f4c0; 收录专栏&#xff1a;JavaEE &#x1f496; 持续更文&#xff0c;关注博主少走弯路&#xff0c;谢谢大家支持 &#x1f496; 单例模式 1. 什么是单例模式2. 饿汉模式3.…

机器学习的一些有趣的点【异常检测】

机器能不能知道自己不知道&#xff0c;而不是给出判断中的一种&#xff1f; Classifier&#xff08;分类&#xff09;Anomaly Detection&#xff08;异常检测&#xff09; 机器能不能说出为什么知道&#xff1f; 有时候可能是因为数据的问题导致了这种错觉。 机器学习是否会有错…

虾皮跨境电商的收款方式及选择指南

虾皮&#xff08;Shopee&#xff09;作为一家知名的跨境电商平台&#xff0c;为卖家提供了多种收款方式&#xff0c;以满足不同卖家的需求。本文将介绍虾皮跨境电商平台的主要收款方式&#xff0c;并提供选择指南&#xff0c;帮助卖家根据自身需求和目标市场选择最合适的收款方…

机器学习---K近邻算法

1. KNN算法 K近邻算法&#xff0c;即K-Nearest Neighbor algorithm&#xff0c;简称KNN算法&#xff0c;是一个理论上比较成熟的方法&#xff0c;也 是最简单的机器学习算法之一&#xff0c;1968年由 Cover 和 Hart 提出。 该方法的思路是&#xff1a;如果一个样本在特征空间…

人工智能中GAN 的五大有趣应用

引言 你能看出这张照片中面部的共同点吗&#xff1f; 这些人都不是真实存在的&#xff01;这些面部图像都是由 GAN 技术生成的。 “GAN” 这个词是由 Ian Goodfellow 在 2014 年提出的&#xff0c;但相关概念早在 1990 年就存在了&#xff08;Jrgen Schmidhuber 开创&#xf…

图像识别中的 Vision Transformers (ViT)

引言 Vision Transformers (ViT) 最近已成为卷积神经网络(CNN) 的竞争替代品&#xff0c;而卷积神经网络 (CNN) 目前在不同的图像识别计算机视觉任务中处于最先进的水平。ViT 模型在计算效率和准确性方面比当前最先进的 (CNN) 模型高出近 4 倍。 Transformer 模型已成为自然语…

【vtkWidgetRepresentation】第十七期 vtkDistanceRepresentation

很高兴在雪易的CSDN遇见你 VTK技术爱好者 QQ:870202403 前言 本文分享vtkDistanceRepresentation相关内容,希望对各位小伙伴有所帮助! 感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步! 你的点赞就是我的动力(^U^)ノ~YO 目录 前言 1. vtkDistanceRep…