0
点赞
收藏
分享

微信扫一扫

C语言-指针

陆公子521 2022-04-29 阅读 107
c语言

一、符号&

        1、作为双目运算符使用,是“位与“运算符。

        2、作为单目运算符,是取地址运算符。

        1)取变量的地址

        2)取函数的地址,例如”&函数名“,即函数的指针,也就是函数代码所在空间的第一个字节的地址。我们往往在使用的时候将&省略,也就是说函数名直接代表函数的指针。函数名与&函数名等价。

        3)取数组的地址,如 int buf[7]={0}; 其中&buf是整个数组的地址,并不是数组第一个元素buf[0]的第一个字节的地址。&buf[0]和buf才是数组第一个元素的地址。

二、符号*

        1、用于组建指针类型

int a=100;
int *p=&a;

此时p和a是两个不同的变量各自拥有自己的独立变量空间:

        a:整型变量,存放整型数100。

        p:指针变量,用于存放整型变量a的指针。

指向也就是说:可以通过这个地址找到对应的空间,并访问它。

        2、解引用

int a = 100;
int *p = &a; 

*p = 200;  //*p:解引用

        此时整个*p代表就是p中指针所指向的空间,也就是a的空间,因此*p=200与a=200的效果一样。在解引用的时候*p是一个整体。

        本质:在解引用的时候,其实是解引用p中的指针,而不是p本身,p只是存放指针的容器。也就是指针变量与指针的关系。

三、获取存储空间地址(指针)的方式

        1、直接获取数字形式的地址

int *p = (int *)0x4234f5e4; // 这里强制转换为int,如果没转,就是普通的整型数
*p = 200; //向0x4234f5e4所指向的空间,写入200

        像这种直接获取的方式其实是有个前提的,就是我们需要事前知道这个地址所对应的空间是可用的:

        1)地址对应的空间存在

        2)这个空间没被占用

        3)空间的访问权限

        这种数字形式的地址,也只有我们嵌入式工程师使用了,因为在开发偏底层的c程序中,往往才会直接通过数字形式的地址来访问地址空间。(通过查阅产品手册得到数字地址)

        2、使用&

int a;
int *p = &a;
*p = 200;

        因为我们并不知道a的指针到底是多少,所以我们无法直接使用数字形式的地址,只能通过&a的方式来代表,编译器会帮助我们把它编程具体的地址。

        这里a并不是指针,&a才是a的指针。

        3、malloc返回地址

int *p = malloc(4);

        malloc从堆中开辟空间,我们也不知道这个空间的指针(第一个字节的地址)是多少,也没办法知道,因为malloc在运行的过程时才会到堆中开辟空间。

        所以只能在运行的过程,让malloc将地址返回并放在p中,然后通过p去间接的使用指针。

        4、某些符号本身就是地址

char *p = "hello wolrd,it is butefull"

        p中存放的是这个字符串所在的常量空间的指针,p指针存放4个或8个字节,这个字符串明显在存放的时候就需要十几个字节,因此p中只能存放字符串的指针,然后通过这个指针去访问常量空间中的字符串。

        还有一种特殊的情况,函数名就是函数的指针,也就是函数代码所在空间的第一个字节的地址。

四、解引用时,指针的使用方式有哪些

        1、直接使用

        2、间接使用

1、直接使用

        1)*((int *)0x43355435) = 100;

        2)如下

int a;
*(&a) = 200;

2、间接使用

        先放在指针变量中,然后通过指针变量去使用。

int a = 10; 
int *p = &a;

*p = 200;

        一定要区别开指针变量和指针的区别,指针变量只是个容器,指针才是真正起作用的。

五、 * 和 & 互为逆向运算符

int a = 100;
int *p = &a;

*p = 200;

        由于p中放的就是&a,解引用是p里面的指针,所以*p=200;实际上就等价于*&a=200;

其实也就相当于这俩符号相互抵消了,这俩符号互为逆向运算符。

六、指针变量空间大小

        所有指针变量的大小(宽度)都是固定的,因为存储空间所有字节的指针都是相同”宽度“的。

  • 比如,如果地址宽度是32位的话,那么每个字节的地址都是32位的
  • 比如,如果地址宽度是64位的话,那么每个字节的地址都是64位的

        既然所有字节的指针的宽度都是一样的,那么所有指针类型的宽度也都是一样的。

        指针变量是用来存放指针的,既然所有指针的宽度都是一样的,那么用来存放指针的指针变量的宽度也是一样的。

        可以测试一下不同系统的地址宽度->

#include <stdio.h>

int main(void)
{
    int *p = NULL;
    printf("%d\n", sizeof(p)); //或者sizeof(int *))

    return 0;
}

七、指针类型

        1、指针类型是什么

        指针类型由基本类型+*构成

int *
float *
...

        2、定义指针变量

        定义的时候,在指针类型的*后面加上变量名即可

int *p;

int **p;

        3、指针类型中基本类型的应用

       Q: 前面不是说了吗,所有指针类型的宽度都是固定的。既然都是固定的,那么我们在种子很类型中区分的那么详细干嘛?

        A:意义就在于,正是由于这些基本类型的存在,因此我们在对指针解引用的时候,才能正确的解释指针所指向的空间。

int a = 100;
int *p = &a;

*p = 10000;

        a的空间有4个字节,访问a的空间需要知道下面三件事:

  • (1)知道a第一个字节的地址,即a指针
  • (2)知道访问哪一个字节时结束
  • (3)知道空间的存储结构

        当*p解引用的时候:

        1)p中存放的就是a指针。

        2)int*的基本类型就是int,所有访问指针所指向的空间的时候,需要访问的空间大小为四个字节。

        3)int*中的int也指明了,在访问指针所指向的空间时,按照整型的存储结构来解析。

        总之,在对指针进行解引用的时候,指针类型中基本类型的作用就是决定对所指向空间的解释方式。

        指针类型都是固定长度的,指针类型中的基本类型,与指针本身宽度无关,至于指针指向空间的宽度有关。

八、对指针强制类型转换

        1、天然的一致

int a = 100;
int *p = &a;

        2、通过强制类型转换来保证类型一致

double a = 100.6;

float *p = &a;            //隐式强制转换
float *p = (float *)&a;   //显式强制转换

        3、强制类型转换做了什么

        在强制类型转换的时候,&a的值没有变,变的只是指针所指向空间的解释方式。

        &a:指针类型为double*

        p:float*

        两边的类型不一致,因此需要做强制类型转换,然后会被以左边的类型进行解析

struct Student
{
    int num;  
    char name; 
    float score;
};

struct Teacher
{
    char name; 
    int num; 
};

struct Student stu = {123, "zhangsan", 87.6};

struct Teacher *stup = (struct Teacher *)&stu; //&stu为结构体指针,即第一个字节的地址

        指针类型被强制转换成struct Teacher *后,通过stup解引用会访问stu空间,这时会以struct Teacher类型进行解析。

九、解释指针

        指针就是一个数,至于这个数怎么解释,要看这个数的类型。

int a = 0;

        &a:为int*的指针,解引用时按照整型来解释&a所指向的空间。

      (int)&a:此时是一个普通的整型数

      (void*)&a:为void*指针,这是一个空类型指针。空类型指针仅仅就是一个指针,不能被解引用,如果要解引用,必须被强制转换为其他具体指针类型,才能进行解引用。

      (struct student *)&a:结构体指针,解引用的时候会按照 struct student结构进行解释。

        在实际编程的时候,一定要慎重使用强制类型转换,避免访问其他非法空间。

举报

相关推荐

c语言---指针

C语言—指针

c语言指针

C语言【指针】

C语言 指针

c语言-指针

C语言---指针

C语言指针

0 条评论