C语言-初探指针

指针概念

  1. 指针是内存中一个最小单元(1个字节)的编号,也就是地址
  2. 平时口语中说的指针,通常指的是指针变量,是用来存放内存地址的变量

int a = 10; //在内存中开辟空间,a是整型变量,占用4个字节的内存空间
int* p = &a; //使用&操作符,取出a的第一个内存单元地址,存放在指针变量pa中,pa的类型是int*

在32位的机器上,地址是32个0或者1组成二进制序列,那地址就得用4个字节的空间来存储,所以一个指针变量的大小就应该是4个字节
如果在64位机器上,如果有64个地址线,那一个指针变量的大小是8个字节,才能存放一个地址
总结:
指针变量是用来存放地址的,地址是唯一标示一块地址空间的
指针的大小在32位平台是4个字节,在64位平台是8个字节

指针和指针类型

指针的类型:char*、short*、int*、long*、……

指针类型意义

指针类型的意义1:
指针类型决定了指针在被解引用的时候访问几个字节
如果是int*的指针,解引用访问4个字节,如果是char*的指针,解引用访问1个字节

在这里插入图片描述

在这里插入图片描述

指针类型的意义2:
指针类型决定了指针±操作的时候,跳过几个字节,决定了指针的步长

在这里插入图片描述
010FFE20 - 010FFE1C = 0x04
0减C,向高位借1,因为是16进制,所以就是16+0=16,16-12( C )=0x04,就是10进制的4

野指针

概念:野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)

如何避免

  1. 指针初始化
  2. 小心指针越界
  3. 指针指向空间释放即使置NULL
  4. 避免返回局部变量的地址
  5. 指针使用之前检查有效性

指针运算

指针±整数

#define N_VALUES 5
float values[N_VALUES];
float *vp;
//指针+-整数;指针的关系运算
for (vp = &values[0]; vp < &values[N_VALUES];)
{
*vp++ = 0;
}

*vp++
先*vp然后vp++,虽然后置++的优先级高,但是后置++是先使用,后++
(*vp)++是*vp指向的内容++

指针-指针

指针-指针得到的是指针和指针之间的元素的个数
不是所有的指针都能相减,指向同一块空间的2个指针才能相减

指针的关系运算

for(vp = &values[N_VALUES-1]; vp >= &values[0];vp--)
{
*vp = 0;
}

实际在绝大部分的编译器上是可以顺利完成任务的,然而我们还是应该避免这样写,因为标准并不保证它可行。
但是标准规定:
允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与指向第一个元素之前的那个内存位置的指针进行比较。

指针和数组

数组名代表首元素的地址,除了
1.sizeof(数组名),计算整个数组的大小,sizeof内部单独放一个数组名,数组名表示整个数组
2.&数组名,取出的是数组的地址,&数组名,数组名表示整个数组
在这里插入图片描述

二级指针

指针变量也是变量,是变量就有地址,那指针变量的地址存放在二级指针中
在这里插入图片描述
对ppa解引用*ppa得到的是pa的值,再解引用**ppa得到的是a的值

指针数组

是数组,是存放指针的数组,存放的类型是int*

#include <stdio.h>

int main()
{
	int a = 1;
	int b = 2;
	int c = 3;

	int* pa = &a;
	int* pb = &b;
	int* pc = &c;

	int* parr[10] = { &a, &b, &c };
	int i = 0;
	for (i = 0; i < 3; i++)
	{
		printf("%d ", *(parr[i]));//1 2 3
	}
	return 0;
}

模拟出二维数组

#include <stdio.h>

int main()
{
	int arr1[4] = { 1, 1, 1, 1 };
	int arr2[4] = { 2, 2, 2, 2 };
	int arr3[4] = { 3, 3, 3, 3 };


	int* parr[4] = { arr1, arr2, arr3 };
	int i = 0;
	for (i = 0; i < 3; i++)
	{
		int j = 0;
		for (j = 0; j < 4; j++)
		{
			//printf("%d ", *(parr[i] + j));
			printf("%d ", parr[i][j]);
		}
		printf("\n");
	}
	return 0;
}

*(parr[i] + j) 和 parr[i][j]是等价的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值