我是靠谱客的博主 简单毛巾,最近开发中收集的这篇文章主要介绍C语言 初识指针2.地址与指针,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

目录

1.指针是什么

2.地址与指针

3.指针的表达式

4..指针与   *

5.指针类型的意义

6.指针的意义

7.我们常说的野指针是什么?该怎么避免?

8.指针的操作

9.指针与数组

10.const与指针


1.指针是什么?

通俗来讲指针可以直接理解成地址。内存中存储着数据,那用户要访问这些数据总要知道去哪里访问吧,这就引申出地址的概念,好比我们国家的街道有名称 有编号,然后根据这些就可以找到对面存放的数据,那么名称,编号在计算机中便是地址,我们可以通过地址找到对应的数据内容,这就有种指向的感觉,因此地址也被称为指针。

2.地址与指针

既然说到地址,那就不得不说&(取地址符),&获得变量的地址(必须是变量),取出的地址的大小取决于编译器是32位编译还是64位编译。

什么是32位编译,即指有32根地址线,他们负责高频通电代表1,低频通电代表0,这样就会有32个代表二进制的数,一个代表一个位(比特),8个比特代表一个字节,因此32个比特最大可以表示4字节的数,因此有时我们打印地址时写成%d可能更结果没啥区别就是因为int也是4字节,但如果是64位就不对了

打印地址一般用%p,或者可以用%x打印16进制数

ps:地址自顶向下连续分配

3.

int* p = &a;

int *p,*q;// int *p,q;

现在看这个表达式,这里表述的意思是p是一个指针,他指向的变量的类型是int,他指向a的地址

第二个是连续定义指针(这里没初始化,就是没让指针指向一个确定的地址)【这种行为非常危险!】

初学者容易写成//右边的内容,但其实这样只定义了一个指针一个int类型的变量.

这里需要注意,p是变量(指针变量),不是*p,只能说可以把*p当成一个整体,是int类型

*p是一个表达式运算的结果,是一个特殊的值,再次强调他不是变量,p才是变量。

4.指针与   *

*是一个单目运算符,用于访问指针所指的地址代表的变量 ps可以靠近int(类型),也可以靠近p(变量)

5.指针类型的意义

前面提到指针的大小只与编译器的位数有关,那么在同一个工程中,char*更int*大小是一样的,那么为什么需要指针类型?

1.指针类型决定了再解引用(*)的时候一次访问几个字节,int*是4个字节,char*是一个,我们前面提到32位是4字节,这代表一个数据占用4字节,假设为10 那么就是00 00 00 0a(16进制,a代表10,拆开就是32个二进制){下面内存存放是倒着的}

【指针的权限】

 如果用char*类型,*pa只能访问一个字节即0a,但是int*可以访问00 00 00 0a

2.还涉及到指针的加减整数 (在数组中)

在c primer plus 上面提到“指针加整数,整数先和指针所指的类型的大小(字节单位)相乘,然后把结果和地址相加”,

即如果p指针指向a[0],p+4就等于a[4]

这又引申出一个问题:如果加完超出数组怎么办?

c语言规定了指针允许指向数组末尾元素的后一个元素,即a[10]是0到9下标,那么a[9]后面那个地址c是允许指针有效的,但是不保证里面的数值(即你可以指,但不能访问)【方便代码简洁】

ps:c没规定可以指首元素的前一个元素哦!

6.指针的意义

为什么要用指针,可能很多初学者会有这个问题,我一开始也是 ,明明靠着数组,循环,函数就能解决很多问题

1.函数需要返回多个值,我们知道return只能返回一个值,那怎么返回多个呢?

这时可以用过指针,解引用操作改变地址中的数据,返回的时候自然能带回改变的数值

2.传递较大变量时,函数的使用是在内存的栈区中的,每次调用函数都会有个压栈操作,即把函数的代码压入栈中,当你一次调用一个很大的数据,栈区可放不下,因此这是可以用过指针指向数组的第一个元素传入函数(数组在内存空间的地址是连续的),传递数组名就是传递首元素的地址,也就是传递指针,某种程度上指针与数组不分家。

3.特殊场景,如函数需要返回状态值,即if(函数返回1,-1,0)这些来判断是否执行,但是我们想在函数执行的同时保留变量的变化,这时可以通过指针来操作变量

等等,指针远远不止上面的操作,还有很多其他用途

指针是c语言为什么能称为最接近底层的语言的原因,当你熟练掌握指针,你可以随心所欲对内存想怎么操作怎么操作。

7.我们常说的野指针是什么?该怎么避免?

野指针就是指针指向的变量未知,这种情况非常危险。加入你不知道并且用*操作他可能就会导致一些奇怪的bug

成因大概分为三种:

1.指针未初始化 int* p; *p=20;

直接对未初始化的指针进行取值操作可能会导致程序崩溃

2.指针越界访问

3.指针指向的空间释放

那么应该怎么避免?

1.初学者一定要记得初始化(你知道指向那个变量就初始化那个变量,不知道就给NULL)记得大写!

2.不用的指针可以及时赋为空指针

8.指针的操作

赋值,解引用,比较,指针与整数相加,两个指针相减

就说一下两个指针相减,前面的前文都有提到

指针相减要求是在同一个数组中,相减可以得到他们的距离(即他们之间有几个元素)

ps:指针相加没有意义,因此指针间没有相加的运算

9.指针与数组

1.数组变量其实是特殊的指针(数组变量本身代表地址)

ps但数组单元表达的是变量需要&

arr=arr[0],arr[0]是arr的一个数组单元

2.在数组中指针+1就是从指针指向的位置跳过一个单元(元素)

3.[]也可以用于指针,

int min=10;
int *p=&min;
printf("%d",p[0]);//等价与printf("%d",*p);

理解:p把min当成一个长度为1的数组,p[0]是第一个元素,因此等价

ps p[]可以有负数,就是向左移

10.const与指针

简单的提一下,分为两种

1.int*const a 

const代表a是一个常数,也就是说一旦这个指针初始化了就不能改变指向了

可以改变指向的变量的值,不可以改变指向的变量,也就是说指向变量a就不能比变了,但是我可以改变a的值

其实数组变量也是上面的类型,为什么说数组与数组之间不可以直接赋值,就是因为int a[ ]等价于int* const a,也就是a本质上是指针,并且不能改变指向

const代表a是常数,初始化出来了就不能被改变,也就是不能代表别的数组

2.const int*a 

可以改变指向,但是不能改变指向的变量的值

可以理解成 const + int*a。int*a可以随便指,但是指完之后被const修饰就变成常量(即不能改变)

3.双const修饰

const int* const a ,啥都不能改变,不能改指向,也不能改值

有什么意义呢?

一般用于保护数据,因为c允许指针访问内存,一旦你做的项目里出现了野指针,并且刚好指向你程序的数据,当你修改的时候也就变相修改了你的内存,这种错误很隐蔽,也很难发现,也很致命。

因此可以用const修饰来达到你针对指向和值的限定

最后

以上就是简单毛巾为你收集整理的C语言 初识指针2.地址与指针的全部内容,希望文章能够帮你解决C语言 初识指针2.地址与指针所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(33)

评论列表共有 0 条评论

立即
投稿
返回
顶部