C语言中指针的说明

2024-06-10 1939阅读

什么是指针?

在C语言当中,我们可以将指针理解为内存当中存储的地址,就像生活当中,一个小区里面,在小区里面有很单元,每一栋单元,单元内的房间有着不同的房间号,我们可以同过几栋几单元去寻找我们想要找到的房间,同样的,我们在C语言当中,指针就是我们寻找想要的房间的一种手段。

指针变量和地址

上面那一段话,已经让我们初步理解了指针

C语言中指针的说明

我们可以看一下这一段代码

其中 0x0115F95C   0x0115F95D   0x0115F95E   0x0115F95F这4个字节代表着a=10所代表的地址,并且每一个字节都是代表着地址

下面我们将通过&(取地址操作符来得到a的地址)

C语言中指针的说明

这边显示的结果是同上面通过内存调试出来的结果是相同的

C语言中指针的说明

这里我们通过&符号将a的地址存储到指针变量p  并且类型为int*的指针

指针变量也是⼀种变量,这种变量就是⽤来存放地址的,存放在指针变量中的值都会理解为地址。

上面那张图我们可以看到  int*p=&a;

那么*p=&a有什么用处呢?

#include
int main()
 {
     int a = 100;
     int* pa = &a;
     *pa = 0;
     return 0;
 }

上面那一段代码我们通过*pa来改变了a的值,结果如下图

C语言中指针的说明

有同学肯定在想,这⾥如果⽬的就是把a改成0的话,写成 a = 0; 不就完了,为啥⾮要使⽤指针呢? 其实这⾥是把a的修改交给了pa来操作,这样对a的修改,就多了⼀种的途径,写代码就会更加灵活, 后期慢慢就能理解了。

指针变量的大小(在VS2022中)

分别为x86以及x64环境下面

C语言中指针的说明

C语言中指针的说明

我们可以看到指针变量的大小在统一环境下面他们的大小是相同的

结论:

• 32位平台下地址是32个bit位,指针变量⼤⼩是4个字节

• 64位平台下地址是64个bit位,指针变量⼤⼩是8个字节 X64环境输出结果

• 注意指针变量的⼤⼩和类型是⽆关的,只要指针类型的变量,在相同的平台下,⼤⼩都是相同的。

指针变量的意义以及和地址的关系

那么指针变量大小有什么意义呢?

我们看下面两段代码

 //代码1 
#include 
 int main()
 {
     int n = 0x11223344;
     int *pi = &n; 
    *pi = 0;   
    return 0;
 }
 //代码2 
#include 
 int main()
 {
     int n = 0x11223344;
     char *pc = (char *)&n;
     *pc = 0;
     return 0;
 }

这两个代码的结果是代码1会将n的4个字节全部改为0,但是代码2只是将n的第⼀个字节改为0。

结论:指针的类型决定了,对指针解引⽤的时候有多⼤的权限(⼀次能操作⼏个字节)。 ⽐如: char* 的指针解引⽤就只能访问⼀个字节,⽽ int* 的指针的解引⽤就能访问四个字节。

指针变量的地址变化

 #include 
 int main()
 {
     int n = 10;
     char *pc = (char*)&n;
     int *pi = &n;
     printf("%p\n", &n);
     printf("%p\n", pc);
     printf("%p\n", pc+1);
     printf("%p\n", pi);
     printf("%p\n", pi+1);
     return  0;
 }

C语言中指针的说明

我们可以看出, char* 类型的指针变量+1跳过1个字节, int* 类型的指针变量+1跳过了4个字节。

这就是指针变量的类型差异带来的变化。

结论:指针的类型决定了指针向前或者向后走⼀步有多大(距离)。

指针运算 指针的基本运算有三种:

• 指针+-整数

• 指针-指针

• 指针的关系运算

野指针

概念:野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)

导致野指针的原因:1. 指针未初始化 2. 指针越界访问 3. 指针指向的空间释放

避免野指针的方面:1.指针初始化 2.⼩⼼指针越界 3.指针变量不再使⽤时,及时置NULL,指针使⽤之前检查有效性 4.避免返回局部变量的地址

assert断言包含在assert.h 头⽂件定义了宏 assert() ,⽤于在运⾏时确保程序符合指定条件,如果不符合,就报错终⽌运⾏。这个宏常常被称为“断⾔”。

assert(p != NULL);

用来 验证变量p是否等于NULL 。如果确实不等于 NULL ,程序继续运⾏,否则就会终⽌运⾏,并且给出报错信息提⽰。

传值调用和传址调用

传值调用

 #include 
 void Swap1(int x, int y)
 {
     int tmp = x;
     x = y;
     y = tmp;
 }
 int main()
 {
     int a = 0;
     int b = 0;
     scanf("%d %d", &a, &b);
     Swap1(a, b);
     printf("交换前: a=%d b=%d\n", a, b);
     printf(" 交换后:a=%d b=%d\n", a, b);
     return 0;
 }

C语言中指针的说明

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

传址调用

#include
void Swap2(int*px, int*py)
 {
     int tmp = 0;
     tmp = *px;
     *px = *py;
     *py = tmp;
 }
int main
 {
     int a = 0;
     int b = 0;
     scanf("%d %d", &a, &b);
     printf("交换前:a=%d b=%d\n", a, b);
     Swap2(&a, &b);
     printf("交换后:a=%d b=%d\n", a, b);
     return 0;
 }

 C语言中指针的说明

我们可以看到实现成Swap2的⽅式,顺利完成了任务,这⾥调⽤Swap2函数的时候是将变量的地址传 递给了函数,这种函数调用方式叫:传址调用。

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

VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]