初学嵌入式——指针详解(一)

当我在使用指针的时候,发现只要有对指针知识点有一点模糊的内容没有理解,就会导致后期使用的时候代码经常报错,因此我决定复习回顾之前指针所学内容,并且分享给大家,如果我有错误的地方和理解不到位的内容,还请大家指正。

一、新手如何理解指针?
1、指针的理解

  • 指针就是地址,地址帮助我们在计算机中找到存储数据的位置

    2、如何学习指针

    在学习指针时,我通常就记住几个知识点,这样辅助我记忆和理解指针

  • 变量 例如 int a;

  • 常量 例如 10;

  • 指针变量 例如 int * p; 指针p的数据类型是int *

  • 取地址符 例如 &a;注意:取地址符不能用在常量上,只能用在变量上

  • 取值符也叫解引用符 例如 *p; 注意 :取值符只能用在地址上,算术运算中的 * 表示乘法符号

  • 数组 int arr[10] ; 注意:在C语言中,数组名表示数组元素的首地址;
    拥有这些知识点之后,我们就能很好的理解指针了

int * p1;//定义指针变量p1, 可以存储int类型数据的首地址
char * p2;//定义指针你变量p2, 可以存储字符类型数据的首地址

指针的大小

32位操作系统的指针大小:4字节,3264位操作系统的指针大小:8字节,64

3、指针的算术运算
指针也能进行算术运算,但是只能进行加法运算和减法运算,实际上就是地址的偏移
偏移大小时,指针指向类型的大小

int * p1;
p1 + 1, 指针指向int型数据的地址,偏移四个字节,地址 + 4 

char * p2;
p2 + 1,偏移一个字节,地址 + 1

long * p3;
p3 + 1,偏移八个字节,地址 + 8 (OS为64),偏移四个字节,地址 + 4(OS为32)

指针-指针 表示两个指针之间的存储位置间隔距离

野指针:对于没有初始化的指针和没有赋值的指针,直接取地址,那么就使用野指针,会出现错误
万能指针:void *;

万能指针 void * ,可以存储任意类型的地址,也可以把void *类型的指针赋值给其他任意类型的指针变量
int a;
float b;

void * p = &a;
p = &b;
int * q = p;
万能指针占用 4/8字节空间存储地址,且只能存储地址,不能进行解引用(不能 *p ),因为指向类型为void,不知道解引用时需要访问几个字节,所以不能解引用
只能转换为其他类型指针进行使用
总结
int a;
&a 是什么类型?是变量还是常量?
int * 类型,常量

int * p = &a;
p是什么类型,*p是什么类型?
p是 int * 类型,*p是 int类型(就是a的空间),按照p的指向类型取大小

*&a == a
&* 两个运算符 是逆运算

&a++ 和 p++
&a++ 错误的
p++,p指针变量 存储的是地址,p++,就是把地址向增大方向偏移一个单位,得到新的地址,然后存储到 p 指针变量中

*p++(*p)++
*p++ : 先算p++,然后取* 运算,运算p++的结果为p,,取*  *p, 但是p += 1
(*p)++ : 先算 *p 得到 a,再进行++

*++p :先p+=1,然后把新的p的值,进行 取 *
p = 0x10*++p ====> ++p  p = 0x14,  *p= *(0x14)

为了防止学不会,请看下面的习题

一  、  选  择  题
1.   变 量 的 指 针 , 其 含 义 是 指 该 变 量 的 ____.

a)值	b)地 址

c)名	d)一 个 标 志

这题很简单,指针是地址,变量的指针就是变量的地址,选b

2. 若 有 语 句  int *point,a=4;和  point=&a;下 面 均 代 表 地 址 的 一 组 选 项 是 __ _.

a)a,point,*&a			b)&*a,&a,*point

c)*&point,*point,&a		d)&a,&*point ,point

这题我们只需要记住&,的用法
&a:是对变量a取值,在用&取a的值,这里的
a是变量,不要认为是一个常量了。
&point :表示对指针变量取地址,再用取这个地址的值,取到的值是指针变量的地址,最后得到变量a的地址,不要理解错了,如果错了,看前面我说的取值符和取地址符的使用方法,还有要明确所取值的对象,这里用&符,取到了指针的地址,这个指针存的是变量地址,所以选d

3. 若 有 说 明 ;int *p,m=5,n;以 下 正 确 的 程 序 段 的 是 ________.

a)p=&n;				b)p=&n;

	scanf("%d",&p);		  scanf("%d",*p);

c)scanf("%d",&n);		d)p=&n;

	*p=n;				*p=m;

这里使用scanf函数,要用到&符,但是%d明确是一个整型,a,b错误
c选项使用了野指针,P没有初始化和赋值,直接取值;选d,*p是变量,能进行赋值操作

4.   以 下 程 序 中 调 用  scanf 函 数 给 变 量  a 输 入 数 值 的 
方 法 是 错 误 的 , 其 错 误 原 因 是__ _____.
main()
{
	int *p,*q,a,b; p=&a; printf(“input a:); scanf(%d”,*p);
	…  …
}
a)*p 表 示 的 是 指 针 变 量  p 的 地 址
b)*p 表 示 的 是 变 量  a 的 值 , 而 不 是 变 量  a 的 地 址
c)*p 表 示 的 是 指 针 变 量  p 的 值
d)*p 只 能 用 来 说 明  p 是 一 个 指 针 变 量

看代码,直接选b,选其他的请去多学

5.   已 有 变 量 定 义 和 函 数 调 用 语 句 : int  a=25;  print_value(&a);  
 下 面 函 数 的 正 确 输出 结 果 是 ______.
void print_value(int *x)

{	
	printf(%d\n”,++*x);
}

a)23	b)24		c)25		d)26

这里我们可以理解为的运算优先级比++高,先计算取值符,把x进行++操作选d;

6.若 有 说 明 : long *p,a;则 不 能 通 过  scanf 语 句 
正 确 给 输 入 项 读 入 数 据 的 程 序 段 是

A) *p=&a;   scanf("%ld", p);

B) long int a ; p=(long *)&a;   scanf("%ld", p);

C) scanf("%ld", p=&a);
D) scanf("%ld"&a)

选a,*p是野指针错误了,其他项是正确项,可以理解一下

7.有 以 下 程 序#include<stdio.h> main()
{   int m=1,n=2,*p=&m,*q=&n,*r; r=p;p=q;q=r; printf("%d,%d,%d,%d\n",m,n,*p,*q);}


A) 1212	B) 1221

C) 2121	D) 2112

这里对指针所指向的数据进行了交换,选b

8.   有 以 下 程 序
main()
{ 	int   a=1, b=3, c=5;
	int   *p1=&a, *p2=&b, *p=&c; *p =*p1*(*p2); printf("%d\n",c);
}执 行 后 的 输 出 结 果 是

	A) 1	B) 2	C) 3	D) 4

选C,(*p2)相当于一个变量,等于3;p1取值乘以p2取值=3

9. 有以下程序main(){
	int a,k=4,m=4,*p1=&k,*p2=&m;a=p1==&m;printf("%d\n",a);}
 程 序 运 行 后 的 输 出 结 果 是
	A 、4	B、 1	C 、0	D、 运 行 时 出 错 , 无 定 值

这里先计算p1==&m,这两个地址不一样,比较结果为0
a=0;选c

10.16 位 编 译 系 统 上 ,若 有 定 义 int	a[]={10,20,30}, *p=&a;, 当 执 行  p++;后 ,
下 列 说 法 错 误 的 是 (	)

	A) p 向 高 地 址 移 了 一 个 字 节	B) p 向 高 地 址 移 了 一 个 存 储 单 元

	C) p 向 高 地 址 移 了 两 个 字 节	D) p 与  a+1 等 价

选a,16位移动两个字节
如果以上都正确的话,你的实力已经接近我了,但是还是得练,毕竟,菜就多练,如果正确率太低,不要着急,去看其他大佬的文章,也能学到东西

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值