指针?什么是指针?(C语言)地址为什么要变成指针才能赋值给指针变量呢?灵魂问题:C语言里指针int *p=&a;相当于int *p; p=&a; int *p=&a;这里面的*p不是表示值吗?值可以等

指针?什么是指针?

从根本上看,指针(pointer)是一个值为内存地址的变量(或数据对象)。正如char类型变量的值是字符,int 类型变量的值是整数,指针变量的值是地址。假设一个指针变量名是 ptr,可以编写如下语句:
ptr=&pooh;//把pooh的地址赋给ptr
对于这条语句,我们说ptr“指向”pooh。ptr和&pooh的区别是ptr 是变量,而&pooh 是常量或者,ptr是可修改的左值,而&pooh 是右值。还可以把 ptr 指向别处:
ptr= &bah;//把ptr指向bah,而不是pooh现在ptr的值是bah的地址。

间接运算符*

假设已知ptr指向bah,如下所示:
ptr=&bah;
然后使用间接运算符找出存储在bah中的值,该运算符有时也称为解引用运算符.不要把间接运算符和二元乘法运算符()混淆,虽然它们使用的符号相同但语法功能不同。
val=*ptr;//找出ptr指向的值
语句ptr=&bah;和val= *ptr;放在一起相当于下面的语句:
val = bah;
由此可见,使用地址和间接运算符可以间接完成上面这条语句的功能,这也是“间接运算符”名称的由来

小结:与指针相关的运算符

地址运算符:&

一般注解:
后跟一个变量名时,&给出该变量的地址
示例:
&nurse 表示变量 nurse 的地址。
间接(或解引用)运算符:*
一般注解:
后跟一个指针名或地址时,*给出存储在指针指向地址上的值
示例:
nurse = 22;
ptr=&nurse;//指向nurse的指针
val=*ptr;//把ptr 指向的地址上的值赋给 val执行以上3条语句的最终结果是把 22 赋给 val。

声明指针

Pointer ptr;//不能这样声明指针
为什么不能这样声明?因为声明指针变量时必须指定指针所指向变量的类型,因为不同的变量类型占用不同的存储空间,一些指针操作要求知道操作对象的大小。另外,程序必须知道存储在指定地址上的数据类型。long和float 可能占用相同的存储空间,但是它们存储数字却大相径庭。下面是一些指针的声明示例
intpi;//pi 是指向int 类型变量的指针
char
pc;//pc是指向char类型变量的指针
float*pf,pg;// pf、pg都是指向float类型变量的指针
类型说明符表明了指针所指向对象的类型,星号(
)表明声明的变量是一个指针。int * pi;声明的意思是pi是一个指针,*pi是int 类型(见图9.5)。

*和指针名之间的空格可有可无。通常,程序员在声明时使用空格,在解引用变量时省略空格。pc 指向的值 (*pc)是 char 类型。pc 本身是什么类型?我们描述它的类型是“指向 char 类型的指针”。pc 的值是一个地址,在大部分系统内部,该地址由一个无符号整数表示。但是,不要把指针认为是整数类型。**一些处理整数的操作不能用来处理指针,反之亦然。**例如,可以把两个整数相乘,但是不能把两个指针相乘。所以,指针实际上是一个新类型,不是整数类型。因此,如前所述,ANSIC 专门为指针提供了%p格式的转换说明

一些处理整数的操作不能用来处理指针,下文进行解释

(C语言)地址为什么要变成指针才能赋值给指针变量呢?

C语言中,指针的值就是地址,不过这个地址不是它自己的地址,而是绑定变量的地址。“指针里面存的东西才是地址”

int point = 0;
int* p = &point ;//声明+初始化
// int* p2_ = point ; wrong synatax
int* p2 = (int* )point ;

所以要初始化一个指针,你得给一个另外的地址。指针p=point 地址,即intp=&point 。此时&point 的值应该是0x010 FFBEC(假设在内存中这个地址存储point )。如果说你硬要把0给p2,你就需要告诉编译器,0是一个地址,同时你还要显式的转换将int转换为int,即intp2=(int*)point。
在不考虑隐式转换/显式转换/自定义数据类型的情况下,只有相同的数据类型才能赋值。要初始化一个指针,你就必须给地址。要给地址,对于一个非指针变量,你要取地址,对于一个指针变量,可以直接赋值。
当然了,你可以这么理解:所有的变量都是有地址属性,只不过大部分都是隐式表现的(所以要&取地址),指针变量则是显式表现的。

为了帮助程序员减少出错。如果编译器不检查数值类型而是直接把一个int数值转换为地址并且不加警告,那么很可能因为程序员的一个粗心(把一个数值错误的赋值给了一个地址)产生灾难性的后果而且几乎无法发现。如果象现在这样必须显式的调用强制类型转换语句再赋值,意味着程序员对这样的转换作了确认,最大可能避免了此类粗心错误。

灵魂问题:C语言里指针int *p=&a;相当于int *p; p=&a; int p=&a;这里面的p不是表示值吗?值可以等于地址&a?

定义变量时,星号属于类型说明的一部分;
赋值时,星号表示对指针所指地址中的值操作(读写)。
而int *p=&a;你都知道了是相当于定义并赋值的简化形式,不应该与单独的 *p=a混淆,等效如下代码:
int *p;
p=&a;
就是将两行代码合并,并省略了重复的 p。

指针赋值
可以分成两种情况
声明+初始化
修改指向

int val = 11;
int *p5 = &val;			//声明+初始化
int *p6 = nullptr;		//设为空指针或者指向其他合法对象
p6 = &val;				//修改指向

为指针赋值,等号右边一定要是地址值,因为指针是一个对象,里面存放的是该指针所指向对象的地址值。

实例:控制LED闪烁

方式一
#if 0
void Delay(unsigned int Time)
while(Time --)
)

int main()
{*//0x11000c40通过以上分析,我们知道需要寄存器GPX2C0N写入数据0x10000000,怎么写
//0x10000000
//GPX2C0N=0x10000000;error
//*0x11000c40=0x10000000;也会报错,因为编译器不知道0x11000c40是个地址,他就把他当做数
*(unsigned int*)0x11000c40=0x10000000;//强制类型转换,显式转换声明这是个指针,
指针类型是unsigned int型,指针前边在加*,变成指针指向的内容,(定义变量时,
星号属于类型说明的一部分;赋值时,星号表示对指针所指地址中的值操作(读写))
编译器不知道0x11000c40是个地址,为何转换成int型,因为是32位,char才8位*
whtle(1)
{
*(unsigned int*)0x11000c44 =0x80;//转换成16进制
Delay(1000000);
*(unsigned int*)0x11000c44=0x00;
Delay(1000000);
}
Return 0;
}
#end if
方式二

c语言中哪种数据类型的元素的地址是连续的,数组和结构体
数组:同一数组的不同数据的类型得一样
结构体:可以是不同的数据类型,int,char,当描述同一个东西的时候,我们会把不同的变量弄到一个结构体中。

void Delay(unsigned int Time)
while(Time --)
)
#define GPX2C0N (*(unsigned int*)0x11000c40)
#define GPX2DAT (*(unsigned int*)0x11000c44)
typedef struct
{
unsigned int CON;
unsigned int DAT;
}gpx2;
//(gpx2*)0x11000c40//显式转换说明这个地址是一个指向这种类型的结构体指针,
它是结构体指针
#define GPX2 (*(gpx2*)0x11000c40)//结构体指针前边再加*,表示结构体的内容
int main()
{
GPX2.C0N =0x10000000;
whtle(1)
{
GPX2.DAT =0x80;//转换成16进制
Delay(1000000);
GPX2.DAT =0x00;
Delay(1000000);
}
Return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不熬夜,早点睡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值