IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C语言指针入门(指针就应该这么学) -> 正文阅读

[C++知识库]C语言指针入门(指针就应该这么学)


一、什么是指针

变量、数组、函数所占存储空间的地址就叫做指针,所以指针就是地址

? ? ? ? 什么是地址:地址就是用于区分不同储存空间的编号。举个生活中的例子,我们把储存空间比喻成一栋楼,那么这栋楼中的每个房子就把储存空间划分为许多块,每个房子有每个房子特有的编号,这个编号就是地址。埋个伏笔:地址只是一个编号,地址有高地址和低地址,但地址大小是统一的,无论是什么类型变量的地址占用内存都是一样大的,例如,我家在302号房,你家在203号房,只能说我家住得比你家高一层,但是不能说我家地址比你家地址占内存空间大。


?

二、指针的类型和用法解析

? ? ? ? 变量指针,举几个例子:int *? ?称为整型指针,char *? 称为字符型指针,float*? ?称为浮点型指针(int*、char*、float*都是变量指针)

????????这里介绍一下 & 这个操作符

具体如下代码

int main()
{
    int a = 2;
    int* p = &a;//&是取地址操作符,这段话的意思就是将a地址取出来赋值给p
    return 0;
}

在命令行int* p = &a;中,&是取地址操作符,这段话的意思就是将a地址取出来赋值给变量p,p里面存放的就是a的地址,看个图容易理解,如下图

如果打印p的值的话,打印的值就是0x00ff1535

要注意的点是int* p = &a;有一层含义,那就是? 变量声明? 和? 变量? 还有? 所赋的值? 都是同一类型,如下图

三个黑框的?类型?都是整型指针,它们的?类型?都是等价的。所以得出一个结论,那就是=左右中的左边? 变量声明(int*)和变量(p),= 右边? 赋值(&a)发的类型都需要相同,言外之意就是什么样类型的变量地址就要赋给同样类型的指针变量。举个反例(也是错误的例子)

int main()
{
    char a = 2;
    int* p = &a;//这里会报错
    return 0;
}

这段代码与上段代码的不同在于对变量a的 类型 声明,这段代码对中a的类型是char,也就是字符型,所以会导致这样的结果,如下图

=右边取a地址&a,取的是字符型a的地址,所以&a的类型是字符型地址,也就是字符型指针,这样=左右类型就有不相同的地方,代码运行时编译器就会报错。 我们又可得到一个结论:整型指针里存放的是整型变量的地址,拓展一下就是:什么类型的指针就存放相同类型的变量的地址


? ? ? ?这里介绍一下 * 这个操作符

#include <stdio.h>

int main()
{
    int a = 2;
    int* p = &a;
    printf("%d",*p);
    return 0;
}

*是解引用操作符

在printf(“%d”,*p)中*p的意思是对指针p解引用,通俗的话说就是解开p中地址的内涵,也就是找出此地址对应存储空间所存的内容(这块存储空间就是变量a,所存内容就是2),言外之意就是

*p 与?a 相等,如果a的内容变化了,*p的内容也变成a变化后的内容 ,如下图所示

根据上述红字结论所说 = 两边类型需要相同,如右图

这时我们回想一下int * p ,p的类型是 int * 也就是整型指针,而* p的类型是 int 也就是整型,我们可以发现*可以看作是和int一体的,也可以看作是和p一体的,这就是 * 的一个特点,如下图

?可能这时候有些人心中会起疑问,那就是int * p到底是代表整型变量呢,还是代表整型指针呢。

这时就是?= 的右边变量所决定的,如下图所示


上述所说基本上都是在介绍int * ,接下来我们说说char * 与int * 的区别:

最明了的就是int*存放整型变量地址,char*存放字符型变量地址。

int main()
{
    int z = 2;
    int* a = &z;
    int* b;
    b = a + 1;
}

说说上面这个代码,每个int变量在内存中占用4个字节,我们定义一个int* a和一个int* b,整型指针变量a是存放整型变量z的地址,b等于a加一,那么此时b存放的分别是什么?下图解

假设a为起始地址,那么a+1得到的结果就是起始地址加四个地址单位,为什么呢?因为a为整型指针变量,a+1中的1是一个int*类型单元,一个整型指针(即int*)的类型单元占内存四个字节,所以a+1后得到的值就是a所存地址向高位移动四个字节即一个int所占内存大小。以此类推

int main()
{
    char x = 1;
    char* c = &x;
    char* d;
    d = c + 1;
}

?每个字符型变量占内存空间一个字节,因为c是地址,所以c+1中的1同样是一个类型单元,与上面int*类型单元不同的是,这个是char*类型,char*类型单元为一个字节,所以加一后则是在c指向的地址上向高位移动一个地址单元(即一个字节)。

所以我们可以知道int的指针加一跳过四个字节,char的指针加一跳过一个字节,结论就是:某个类型所占内存空间的字节数就是此类型指针变量加一后跳过的字节数。


三、指针的应用

? ? ? ? 指针的应用场景很广,由于上述介绍不全面,所以以下只说一个例子。

? ? ? ??自定义函数传参

在我们定义的函数中如果需要改变main函数或者其他函数中的变量时,不通过返回值传递出去的话还有什么办法呢?那就是指针,根据前面的介绍,指针是地址,而我们对地址解引用即可操作地址指向的变量,如下代码

void Addb(int* x)
{
    int b = 5;
    *x = *x + b;
}

int main()
{
    int a = 2;
    Addb(&a);
    printf("%d",a);
}

我们打印出来的a应该是等于7的

这个时候有人就会问:为什么定义Addb的时候()里面不直接写int x,然后main里面直接写? Addb(a);呢,大家可以试一下以下代码这样写打印的结果是什么

void Addb(int x)
{
    int b = 5;
    x = x + b;
}

int main()
{
    int a = 2;
    Addb(a);
    printf("%d",a);
}

答案是打印了2

有同学会问:为什么啊?明明Addb(a);中传过去了a,为什么a还是2。

解释:因为Addb(a);传递的是形式参数,形式参数的意思是只有值,但不代表实际的参数,形式参数只是实际参数的临时拷贝,通俗点说就是传了a的值,但没有把这个变量a传过去,一个成语形容就是:虚有其表

那又有人问,为什么传指针却可以改变a,那是因为指针就是地址,内存的地址是不变的,只要找到a的地址就能改变a里面的值。

---------------------------------------------------------------------------------------------------------------------

另一方面

? ? ? ? 自定义函数传参

如果我们定义了一个很大的数组,例如有2000个元素,如果我们选择传递形参的方式,形参就要对实参进行拷贝,相当于占用了内存4000个此元素类型的空间,这就十分不合理,因为内存空间是有限的,所以我们在自定义函数中传递数组并不是传递形式参数而是传递数组某个元素的地址(最常用的是传递数组首元素地址)

void Addb(int arr[] ,int i)
{
    arr[i] = i*2;
}

int main()	
{
	
	int a[2000] = {0};
	Addb(a,0);

}

这里Addb(a,0)里面的a就是数组首元素地址,指针中级篇再介绍数组指针


介绍到这,谢谢大家观看。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-01-28 11:42:41  更:2022-01-28 11:43:49 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 9:26:39-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码