C语言基础级——指针定义(1)

C语言基础级——指针定义(1)

转载请标明出处!

C语言指针,这部分应该是C语言的核心,也是较为复杂的知识,想要学懂并灵活运用起来,对于小白来说要去慢慢的啃。推荐一本书籍《C和指针》,这本书融合了指针与数组、函数、字符串等等,网上有很多电子版本,可以自己去搜检。或者如果大家有需要,可以私信我~~~

指针内容比较多,所以分为几部分,展示给大家,这些我会陆陆续续更新。

  • 指针定义
  • 指针数组、数组指针
  • 字符串指针
  • 指针函数、函数指针
  • 指针、数组、函数
  • 结构体指针
  • 指针、结构体、函数

本节内容主要讲解指针的各个运算符的含义,以及如何普通数据类型与指针数据类型大小为何不同。

1 取址符:&

1.1 普通变量取址

先实现输出变量值,然后输出变量所在的地址。第二部分&param它的意思是取出param变量的地址,并通过printf打印其地址。

int param = 5;

// 打印param的变量值与地址
printf("%d %p\n", param, &param);

在这里插入图片描述
在这里插入图片描述

1.1.1 图解:

别名:给 0x7ffff09f67cf4 地址取个名字叫paramparam空间存放的是int类型的内容。&param就是该空间的地址(0x7ffff09f67cf4),我们就可以通过这个方式查找到param变量在内存当中的地址,&是地址运算符。
这里的输出地址每一次执行都是会变化的

1.1.2 地址运算符和位运算符区别

&运算符符号,其实在取址和位运算当中,一个是单目运算符,另一个是双目运算符。

  • 取址&代表的是取地址符。
  int a = 5;
        
  printf("%d\n", &a);

在这里插入图片描述

  • 位运算&代表的是完成与运算。
 int a = 5;
 int b = 5;
        
 printf("%d\n", a & b);

在这里插入图片描述

注意:

两种写法是等价的。

int num = 5;
int *ptr;

// 这两个也是等价的
ptr = #
ptr = & num;

2. 指针变量

// 定义一个指针变量ptr
int *ptr;
// 定义一个普通变量
int param = 5;

// ptr指针变量空间存放param的地址
ptr = &param;
  1. ptr当作变量来看,那我们知道 &param 是取普通变量本身的地址。
// 输出param的内存地址
printf("&param addr = %p\n", &param);
  1. &ptr就是取指针变量本身所在的地址。
// 输出ptr的内存地址
printf("&ptr addr   = %p\n", &ptr);
  1. ptr = &param, ptr指针指向param地址。或者可以理解为指针变量ptr,本质上它也是一个变量,只是它存放的是param普通变量的地址;
// 输出ptr所保存的地址
printf("ptr addr    = %p\n", ptr);

把上述整合一起:

#include<stdio.h>

int main()
{
    
    
    // 定义一个指针变量ptr
    int *ptr;
    // 定义一个普通变量
    int param = 5;

	// ptr指针变量空间存放param的地址
    ptr = &param;

    // 输出param的内存地址
    printf("&param addr = %p\n", &param);
    // 输出ptr的内存地址
    printf("&ptr addr   = %p\n", &ptr);
    
    // 输出ptr所保存的地址
    printf("ptr addr    = %p\n", ptr);

    return 0;
}

在这里插入图片描述
在这里插入图片描述

2.1 间接运算符:*

*ptr的作用是,通过存放在内部的地址(0x7ffdd2d2fb1c),查找到这个地址(0x7ffdd2d2fb1c)里面所存放的值(2)。这个过程其实相当于通过*ptr间接的取出里面的值。(从param也能直接取出里面所存放的值)。
在这里插入图片描述

注意:

  • 间接运算符*和 数学相乘运算符*它们不要混淆一起。
  • 两种写法是等价的。
// 等价
int *ptr;
int* ptr;

3. 声明数据类型

简单回顾一下,各个数据类型各占内存空间大小。

#include<stdio.h>

int main()
{
    
    
    // 打印各个数据类型所占的字节数
    printf("int    = %ld\n", sizeof(int));
    printf("char   = %ld\n", sizeof(char));
    printf("float  = %ld\n", sizeof(float));
    printf("double = %ld\n", sizeof(double));
    return 0;
}

在这里插入图片描述

那么不同类型的指针变量是否也和上述的一致呢?一起来先看下实验测试。

#include<stdio.h>

int main()
{
    
    
    printf("int*    = %ld\n", sizeof(int*));
    printf("char*   = %ld\n", sizeof(char*));
    printf("float*  = %ld\n", sizeof(float*));
    printf("double* = %ld\n", sizeof(double*));
    return 0;
}

在这里插入图片描述

实验证明出结果并不一致,与我们猜想完全不一样。这是为什么呢?其实,这和我刚开篇说提到的指针特性有关,C语言指针内部用来存放地址。 地址字节数和系统的位数有关,系统和编译器为64位,那地址空间大小占8个字节;如果系统和编译器为32位,那地址空间大小占4个字节。所以我们先认清楚第一个,指针变量所占的字节数和系统的位数有关系的。

那么接下来我们会产生两个疑问,第一个是指针变量前面的数据类型有什么作用呢?第二个是指针变量本身空间又是什么类型?

  1. int* ptr,它代表的是当前的指针 ptr 所指向的值 *ptr 的为int类型,也就是param存放的数据类型。
int param = 5;
int *ptr;
ptr = &param;
  1. *ptr 本身存放空间的是地址,那这段空间地址是为空数据类型(也就是 void* ),它既不是 int* 也不是 char*,大多数的系统当中,内存地址数据类型都是用空数据类型来表示的。

注意:

int param = 5;

// 两者等价的
int *ptr = &param;

int *ptr;
ptr = &param;

这两者也是等价的,大家对这个等价关系也会产生疑问吧?如何去解释?

  • 第一种解释:

    • 第四行:给 *ptr 分配了四个字节空间(0x7ffdd2d2fb20)的同时,在空间内存放地址(0x7ffdd2d2fb1c)。
      在这里插入图片描述

    • 第七行:先给 *ptr 分配四个字节空间(0x7ffdd2d2fb20),完成此步骤后,再给 *ptr 空间内存放param地址(0x7ffdd2d2fb1c)。
      在这里插入图片描述

  • 第二种解释:

普通变量表示:

int param = 5;

int ptr = 5;

int ptr;
ptr = 5;

再变换:

int param = 5;

int ptr = &param;

int ptr;
ptr = &param;

最后变化:

int *ptr 转换成 int* ptr,我们有说过指针变量本质上是一个变量。

int param = 5;

// 两者等价的
(int*) ptr = &param;

(int*) ptr;
ptr = &param;

猜你喜欢

转载自blog.csdn.net/qq_43125185/article/details/110244093