C语言学习day5--指针

1、概念

  • 指针就是地址,地址就是指针
  • 什么是地址?
    • 在内存中,由多个内存单元构成,每个内存单元占8位(bit) —> 1字节,内存中以字节为单位;

每一个字节都有相应的编号,这个编号就叫做地址。

  • 地址具有唯一性。
  • 32位机
    • 代表寻址能力

最小地址编号 0000 0000 0000 0000 0000 0000 0000 0000            —>0x00000000

最大地址编号 1111 1111 1111 1111 1111 1111 1111 1111            —>0xffffffff

  • 指针是 指针变量、地址、指针 的统称
    • 指针变量:用来存储不同地址常量【用来存储地址】

2、指针变量

(1)指针变量的定义

<存储类型><数据类型> * <变量名>;        // * 用在定义变量时,表示该变量是一个指针变量

int *p;                                                      // 表示定义一个整型的指针变量 p

(2)指针变量的初始化

char *q = NULL                                         //指针q 指向零地址空间,避免成为野指针

【NULL 代表零地址空间,该空间既不允许读 也不允许写】

【野指针是随机的、不正确的、没有明确限制的】

【野指针不能被赋值,但可以给予指向】

(3)直接访问与间接访问

直接访问:直接通过变量的地址访问

间接访问:通过存储该变量的地址的指针变量去访问

(4)指针的运算

1)&:

取地址,取变量的地址

     * :

1.乘 运算符

2.定义指针

3.取内容,取指针指向变量的内容

【 & 与 * 互为逆运算 】

2)指针的偏移

p + 1 :以p所指向的地址为基准,向高地址偏移1个数据类型(指针所指向的数据类型)的大小

     int a=10;int *p=&a;p+1往高地址偏移4个字节

p - 1 :以p所指向的地址为基准,向低地址偏移1个数据类型(指针所指向的数据类型)的大小

p + n :以p所指向的地址为基准,向高地址偏移n个数据类型(指针所指向的数据类型)的大小

p - n :以p所指向的地址为基准,向低地址偏移n个数据类型(指针所指向的数据类型)的大小

3)++ / --

单独使用

p++:以p所指向的地址为基准,向高地址偏移1个数据类型(指针所指向的数据类型)的大小

p - -:以p所指向的地址为基准,向低地址偏移1个数据类型(指针所指向的数据类型)的大小

++p:以p所指向的地址为基准,向高地址偏移1个数据类型(指针所指向的数据类型)的大小

- - p:以p所指向的地址为基准,向低地址偏移1个数据类型(指针所指向的数据类型)的大小

结合使用

*p++:          p先与++结合,此时p的指向要变,输出不变

(*p)++:   p先与 * 结合,此时p的指向不变,输出不变

*++p:          p先与++结合,此时p的指向要变,输出要变

*(++p):   和 *++p相同

4)-

p - q:必须要数据类型相同,输出相差的元素个数

(5)指针的数据类型

指针的数据类型与其所指向的数据类型相同

(6)指针的字节大小

只有主机的位数有关

64位 指针的空间大小位8个字节

// 指针表示地址,地址位数 = 主机位数 / 8;

3、指针与一维数组

int a[5] = {10,20,30,40,50};

一维数组 数组名:

  • 代表整个一位数组空间
  • 代表首元素地址

[ ]:变址运算符(偏移并引用)

int a[5] = {10,20,30,40,50};

a[0] <==> *(a + 0);

int *p = a;

*(a + 0) <==> *(p + 0);

a[0] <==> *(a + 0) <==> *(p + 0);

4、指针与字符串数组

char s[ ] = "hello";

char *p = s;

puts ("hello");

// 定义一个字符指针q,指向指向字符串常量的首元素;

char *q = "hello";

puts (q) ;

printf ("%p\n", s);

printf ("%p\n", q);

// q指向字符串常量“hello”的首地址,不能修改常量的值;

*q = 'A';

5、多级指针——指向指针的指针

用来保存指针变量的地址,用 ** 来定义变量

(1)二级指针

<存储类型> <数据类型> **<变量名>;

eg:

int a = 10;

int *p = &a;

int **pp = &p;

printf(“%d”,**pp);               // 输出:10

6、指针与二维数组

int a[2][3];

int *p = &a[0][0];

7、数组指针

int a[ ] = {1,2,3};

int (*p)[3] = &a;      // 定义一个行指针变量 p

分析:

a = &a;值相同,但引用的内存空间不同!!!

a 表示数组首元素的地址;

&a 表示整个数组的地址;地址值 = 数组首元素的地址值;

a + 1 偏移4字节;

&a + 1 偏移12字节(元素个数 * 4);     【16进制,一个字符4字节】

*&a = a;             // * 与 & 互为逆运算,【记忆方法:&升维(增加引用空间,* 降维(降低引用空间】

*(*&a + 1)= 2             // 2为a[2]的值;

*&a + 1;   偏倚4字节

*(*&a + 1);     先偏移4字节,再取当前地址空间的内容

(1)定义数组指针

<存储类型> <数据类型> (*<指针变量名>)[元素个数];

元素个数:一次能引用的元素个数【一般写列的个数】

int (*p)[3];

eg:

int a[2][3] = {0};

int (*p)[3] = &a;           // 定义后,p表示数组a 的首行地址,引用空间为12字节

二维数组的数组名代表首行的地址

8、指针数组

存储大量同类型的指针变量

(1)一般形式

<存储类型> <数据类型> * 数组名[数组元素个数]

int *p[3];       // 定义一个指针数组,该数组存储int *类型的指针

(2)main函数参数

argc:代表命令行参数个数

char *argv[]: 指针数组,用来保存命令行参数中的字符串

9、特殊指针

(1)万能指针——能访问任意类型的指针

int a=10,b=20,c=30;

void *p = &a;

【万能指针不能直接接引用,取内容前必须强转为某一数据类型】

printf(“%d”,*(int *)p);

(2)const 修饰指针

1)const int *p = &a;

     *p = 100;       // 错误

     p = &b;

【可以修改指针的指向,但不能修改指针指向空间的内容】

2)int * count p = &a;

     *p = 100;

     p = &b;           // 错误

【不能修改指针的指向,可以修改指针指向空间的内容】

3)count int * count p = &a;

     *p = 100;         // 错误

     p = &b;           // 错误

【既不能修改指向,也不能修改指针执行空间的内容】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值