重拾C语言之指针篇(一)

职业发展需要,得把C语言重新捡起来,基础的东西这里就不介绍了,把重点难点归纳总结下,有不当之处请予指正。

 1、关于内存

学指针,应该先了解下内存。程序只有装载到内存中才能被执行。我们知道在计算机中,一切信息都是以二进制形式存在的。计算机中是以字节(也就是8个二进制位)为最小存储单元储蓄数据的。而内存是由按顺序编号的一系列存储单元组成的,在内存中,每个存储单元都由唯一的地址,通过地址可以方便地在内存单元中存储信息。

    2、指针

通俗来讲,我们把指向某一内存单元的地址称为指针(ps:指针不等于地址,后面我们会详细说明),用来存放指针的变量我们称之为指针变量,通常我们也称指针变量为指针。


指针的声明和初始化

指针声明的格式  :数据类型 *标识符,如:

int *p1;
char *p2;
double *p3;

指针作为地址是有大小的,其大小是固定的32位 4个字节。我们可以使用sizeof()来获得指针的大小。

sizeof(p1);//结果是4;


在声明一个指针后,编译器并不会自动完成其初始化,此时,指针的值是不确定的,指针指向那块内存单元是完全随机的。所以指针在使用之前必须初始化:

 int a = 100;
int *p = &a;//初始化一个指针,&是取地址符,即把a的地址取出,付给指针变量p;

如果在指针变量声明之初不知道该将此指针指向何处,可以将其置“0”,即将指针变量指向0X00000000地址,C语言中提供了关键字NULL。

int *p;
p = NULL;//  p = null就是指针p指向0X00000000的地址

我们可以通过%p打印出指针变量的值

int num =100;

int *p = #

printf("%p",p) //此处打印的是指针变量p的值,即num的地址

printf("%x",&num) //此处同样可以打印出变量num的地址



*运算符

*是指针运算符,返回指针所指向的对象的值。通过*运算符我们可以直接或间接的访问变量的值

直接访问:

int num = 100;

*(&num)//通过变量num的地址直接访问,&num是取出num的地址

间接访问:

int num = 100;

int * p = #

printf(“%d”,*p)//此时打印出num的值,通过指针变量间接访问变量num


指针与地址

前面已经提过地址是有大小的,而且是固定的,长度为32位 4个字节,而指针是用来存放地址的。指针有其类型,指针类型,指的是声明指针变量时位于变量名前的“类型*”,如:

int * p;//int 型

char *p1;// char型

double p2;//double型

指针的类型决定了指向的数据大小,决定了数据的解析方式。

int num = 100;

int * p = #//假设num地址为100200;因为int是4个字节的,那么指针从100200开始往前读取4个字节读取变量num的值,

同理:

double d = 23.0;

double *p = &d; //假设d地址为200300;因为double是8个字节的,那么指针从200300开始往前读取8个字节读取变量d的值.



不同类型指针不可随意赋值

因为指针不见决定内存指向,还决定指向数据大小和数据解析方式。所以不同类型的指针不能随意赋值

int a = 100;

char ch = 'A';

double d = 11.0;

int *p1;

char *p2 ; 

double *p3 ; 

p1 = &d; 

printf(“%d”,*p1)//p1是int类型,按地址读取数据时往前读取4个字节,而d是double型,占8个字节。故读取出错,*p1只读取了前4个字节的内容,所以读取内容会出错,读出来的数据不是想要的。

p2 = &a;

printf(“%c”,*p2 )//同理,不可能打印出准确的值。int 4个字节,char占1个字节。

不同类型指针赋值会出现指向内存字节数大于指针类型占据的字节数或者小于指针类型占据的字节数


同类型指针赋值后,改变其中一个必然影响另一个指针的指向的值

int num1 = 100;

int num2 = 200;

int *p1,*p2;

p1 = &num1;//p指向变量num1

p2 = p1 ;//p2也指向num1

*p2 = num2  //p2指向num2,此时,p1也指向num2 即*p1 = *p2 =num2;



指针的运算

指针变量也是一种变量,可以进行简单的运算,但指针的运算主要局限在加减算术和其他一些为数不多的特殊运算。

整数与指针最好不要直接进行赋值运算

int *p = 5;//理论上可以给一个指针传一个数值,但是不能随便传,可能这个内存地址被其他程序所占用


int a[5] = {1,2,3,4,5}

printf(“%x”,a)//a被编译器当成数组的首地址;

使用递增/递减运算符(++ --)将指针递增或递减

指针的++、--只有在数组内部才有意义。指针++就是按照指针类型的大小,前进一个类型的大小sizeof(),int,前进四个字节

指针加上1,在数组内部等价于向后移动1个元素的大小,指针减去1,等价于数组内部,向前移动1个元素的大小.

指针的加减法在非数组内部没有任何意义,而且很容易越界报错,一个exe不能读写其他exe进程的内存。


指针之间的比较

指针只代表了“位置”这么一个信息,所以对两个毫无关联的指针比较大小没有意义。如果两个指针所指向的元素位于同一个数组(或同一块动态申请的内存中),指针的大小比较反映了元素在数组中的先后关系,通过指针指向数组中的元素,来比较数组元素的地址哪个靠前。指针是否相等,可以判断是否指向同一地址。












  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值