C语言指针详解(1)

1.指针是什么

        在计算机中内存被划分为一个个单元格,每个单元格都有个编号被称为地址,也叫做指针。

                                                  C语言指针详解(1)_第1张图片

        计算机上CPU(中央处理器)通过地址来访问内存的某个字节空间

1.1如何得到一个一个变量的地址 

int main()

{

        int a = 10;//向内存申请一块空间

        int*p=&a;//用取地址操作符&将a的地址放到指针变量p中

        printf("%p",p);//%p打印地址

}

1.2指针的类型和大小 

运用下面代码计算不同指针大小

int main()
{
        printf("%d ", sizeof(void*));//特别提醒void*指针不能直接进行指针+-整数和解引用的运算
        printf("%d ", sizeof(char*));
        printf("%d ", sizeof(short*));
        printf("%d ", sizeof(int*));
        printf("%d ", sizeof(float*));
        printf("%d ", sizeof(double*));    
}//通过运行代码得到结果全部为8

这里进行补充: 指针大小在32位平台里是4个字节,在64位平台中是8个字节

那么既然指针大小都是8个字节,那还区分指针类型干嘛?有什么意义吗?

int main()//代码1

{

        int a = 0x11223344;
        char* pc = &a;
        *pc = 0;//(*)为解引用操作符,*pc就是通过pc中存放的地址,找到指向的空间

}

int main()//代码2

{

        int a = 0x11223344;
        int * pc = &a;
        *pc = 0;

运行代码发现代码1得到的结果是11223300,而代码二得到的结果是0.由此可以知道指针类型决定了指针进行解引用时,可以访问空间的大小。

总结:

char *pc        pc可以访问1个字节

int * pc        pc可以访问4个字节

double* pc        pc可以访问8个字节

下面看一段代码来直观表示一下

C语言指针详解(1)_第2张图片

可以看到字符指针+1向后跳了一个字节,整型指针+1向后跳了四个字节,双精度浮点型指针+1向后跳了八个字节。

由此可以得出:指针的类型决定了指针向前或向后走的距离。

野指针

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

野指针的成因:

1.指针未初始化

int main()

{

        int *p;//局部变量指针未初始化,默认为随机值

        *p=4;

}

2.指针越界访问

int main()

{

        int a[10]={0};

        int *p=&a[0];

        for(int i=0;i<11;i++)

                (*p++)=1;//当i等于10时造成指针越界访问

3.指针指向的空间释放

 int *test()

{

        int n=10;//n为局部变量,函数退出后变量销毁

        return &n;

}

int main()

{

        int *p=test();

}

 如何规避野指针

1.指针初始化

int main()

{

        int n=10;

        int *p1=&n;

        int *p2=NULL;//p2目前还不知道指向哪里,先给它赋值NULL

}

2.小心指针访问越界

3.指针变量不再使用时,及时置NULL,指针使用之前检查有效性

int main()

{

        int a[10]={0};

        int *p=&a[0];

        for(int i=0;i<11;i++)

                *(p++)=1;

        p=NULL;//指针p越界了,及时将其赋值NULL

        ……

        p=&a[0];

        if(p!=NULL)//使用时进行判断不为NULL时再使用

        {

                ……

        }

4.避免返回局部变量地址 如上(test())

野指针和悬空指针区别

悬空指针是指指针变量在声明后没有被初始化的情况下被使用,或者指针指向的内存已被释放,但指针变量没有被置为NULL。

野指针是指指针指向的内存地址已经被释放或者指向的对象已经被销毁的情况下继续被使用。

assert断言

assert函数头文件

用于运行时确保程序符合指定条件,如果不符合就报错终止运行。可以用于避免野指针。

assert(p!=NULL);

 assert优点:

1.能自动标识文件和出错的行号

2.可以无需更改代码就开启或关闭assert

在确认程序没有问题的情况下,不需要在使用断言,就在#include前面定义一个宏NDEBUG

#define NDEBUG

#include

assert缺点:引入额外检查,增加了程序的运行时间 

你可能感兴趣的:(C语言进阶,c语言,开发语言)