c语言指针--初步

  1. 指针是什么
  2. 指针与指针类型
  3. 野指针
  4. 指针运算
  5. 指针与函数
  6. 二级指针
  7. 指针数组

1指针是什么

指针是内存中最小单元的一个编号,也就是地址

口语中的指针是指针变量,用来存放内存地址的变量

一个小的单元是一个字节

对应32位机器,假设有32跟地址线,每根地址线在寻址时产生高低电平(0或1),产生地址为2的32次方  :2^32/1024kb==2^32/1024/1024mb/2^32/1024/1024/1024==4GB        

地址是唯一标识一块内存地址的,指针在32位机器上是4字节,在64位机器上是8字节

指针变量是4个字节,可以指向内存大小取决于类型

2指针类型

2.1意义是决定指针解引用时可以访问几个字节

int a = 0x11223344;
	int* pa = &a;
	int* pb = &a;
	printf("%p", *pa);
	printf("%p", *pb);
	//可以访问的地址不一样所以+1后地址不一样
	printf("%p", *pa+1);
	printf("%p", *pb+1);

2.2指针类型决定指针+1/-1时可以跳过几个字节(决定指针的步长)

3野指针

指针指向的位置是不可知的,

造成原因是

1指针未初始化

2指针越界访问

3指针指向的空间释放

如何减少

1初始化

2避免越界访问

3指针指向空间释放及时置空

4避免返回局部变量的地址

5使用前检查他的有效性


4指针运算

4.1指针+-整数

* vp++ = 0;
先*vp
再vp++
(* vp)++ = 0;
这种是对解引用的对象++
//给数组每个元素赋值1
int main()
{
	int arr[10] = { 0 };
	int i = 0;
	int sz = sizeof arr / sizeof(arr[0]);
	int* p = arr;
	for (i = 0; i < sz; i++)
	{
		*p = 1;
		p++;
	}

 等价与

int arr[10] = { 0 };
	int i = 0;
	int sz = sizeof arr / sizeof arr[0];
	for (i = 0; i < sz; i++)
	{
		arr[i] = 1;
	}

4.2指针-指针

指针-指针得到的是指针之间的元素的个数,,指向同一块空间的两个指针才能相减

int arr[10] = { 0 };
	printf("%d\n", &arr[9] - &arr[0]);//9

应用

结合之前学习三种方式写的my_strlen

1
int my_strlen(char* str)
{
	int count = 0;
	while (*str != '\0')
	{
		count++;
		str++;
	}
	return count;
}
2递归方法
int my_strlen(char* str)
{
	if (*str != '\0')
	{
		return 1 + my_strlen(str + 1);
	}
	else
		return 0;
}
3指针-指针
int my_strlen(char* p)
{
	char* start = p;
	while (*p != '\0')
	{
		p++;
	}
	return (p - start);
}

4.3指针的关系运算

标准

允许指向数组元素的指针与指向 数组最后一个元素后面内存的指针进行比较,但不允许与指向数组指向第一个元素的位置的内存进行比较

5指针与数组

数组是一组相同类型的元素集合

指针就是地址

指针变量是一个变量存放的是地址

因为数组名是是数组首元素的地址由此建立联系(有两种例外)

int arr[10] = { 0 };
	int i = 0;
	int sz = sizeof arr / sizeof arr[0];
	int* p = arr;
	for (i = 0; i < sz; i++)
	{
		printf("%d\n", arr[i]);
		printf("%d\n",*(p+i));
		printf("%d\n",*(arr+i));
	}

6二级指针

用来存放一级变量的地址的地址

	int** ppa = &pa;//int*说明ppa指向的对象是int*,后一个*说明ppa是指针

7指针数组(好孩子)本质是数组

存放指针的数组 

int a = 10;
	int b = 20;
	int c = 30;
	int* parr[10] = { &a,&b,&c };//指针数组

与二维数组的比较

int arr[3][4] = { 1,2,3,4,2,3,4,5,3,4,5,6, };
	//1 2 3 4
	//2 3 4 5
	//3 4 5 6 
	int i = 0, j = 0;
	for (i = 0; i < 3; i++)
	{
		for (j = 0; j < 4; j++)
		{
			printf("%d", arr[i][j]);
		}
		printf("\n");
	}
int arr1[4] = { 1,2,3,4 };
	int arr2[4] = { 2,3,4,5, };
	int arr3[4] = { 3,4,5,6 };
	int* parr[3] = { arr1,arr2,arr3 };
	int i = 0, j = 0;
	for (i = 0; i < 3; i++)
	{
		for (j = 0; j < 4; j++)
		{
			printf("%d ", (parr[i][j]));//?parr【i】拿出是arr1的地址&arr1【j】;
//	printf("%d ", &arr1[1]);为什么这样不行
		}
		printf("\n");
	}

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值