C语言---指针(上)

1.指针变量和地址

1.1 取地址操作符(&)

#include <stdio.h>
int main()
{
	int a=10;
	//&a;取出a的地址
	printf("%p\n",&a);
	return 0;
}

&a 取出的是a所占4个字节中地址较小的字节的地址

1.2 指针变量和解引用操作符(*)

1.2.1 指针变量

我们通过取地址操作符取出一个地址,必须储存起来,那我们应该放在哪里呢?(指针变量中)

int a=10;
int *p=&a;//p就是指针变量,取出a的地址并储存在p中

指针变量也是一种变量,这种变量就是用来存放地址的

1.2.2 如何拆解指针类型
int a=10;
int *p=&a;

这里int*中的*是在说明p是指针变量,而前面的int是在说明p指向的是整型类型的对象
在这里插入图片描述

1.2.3 解引用操作符

我们只要拿到了地址(指针),就可以通过地址(指针)找到地址(指针)指向的对象

#include <stdio.h>
int main()
{
	int a=10;
	int *p=&a;
	*p=0;
	return 0;
}

*p就是通过p中存放的地址,找到指向的空间,*p其实就是变量a。所以*p=0;这个操作就是把a改成0

1.3 指针变量的大小

  • 32位平台下地址是32个bit位,指针变量大小是4个字节
  • 64位平台下地址是64个bit位,指针变量大小是8个字节
  • 注意指针变量的大小和类型是无关的,只要指针类型的变量,在相同的平台下,大小都是相同的。

2.指针变量类型的意义

2.1 指针的解引用

指针的类型决定了,对指针解引用的时候有多大的权限(一次能操作几个字节)
例如:char*的指针解引用就只能访问一个字节,而int*的指针的解引用就能访问4个字节

2.2 指针+ - 整数

在这里插入图片描述
我们可以看出,char*类型的指针变量+1跳过一个字节,int*类型的指针变量+1跳过了4个字节

结论:指针的类型决定了指针向前或者向后走一步有多大距离

2.3 void*指针

这种类型指针可以用来接受任意类型的地址。但是具有局限性,void*类型的指针不能直接进行指针的+ - 整数和解引用的运算
一般void *类型的指针是使用在函数参数的部分,用来接收不用类型数据的地址

3.const修饰指针

3.1 const 修饰变量

变量是可以修改的,如果我们在变量前面加上const之后,该变量就不能被修改了

#include <stdio.h>
int main()
{
	int m=0;
	m=20;//m可以被修改
	const int n=0;
	n=20;//n不能被修改
	return 0;
}

3.2 const修饰指针变量

一般来讲const修饰指针变量,可以放在*的左边,也可以放在*的右边,意义是不一样的

int *p;//没有xonst 修饰
int const *p;//const 放在*的左边修饰
int *const p;//const 放在*的右边修饰

结论:

  • const如果放在*的左边,修饰的是指针指向的内容,保证指针指向的内容不能通过指针来改变。但是指针变量本身的内容可以改变
  • const如果放在*的右边,修饰的是指针变量本身,保证了指针变量的内容不能被修改,但是指针指向的内容,可以通过指针改变

4.指针运算

4.1 指针 + - 整数

因为数组在内存中是连续存放的,只要知道了第一个元素的地址,就能找到后面所有的元素

int arr[10]={1,2,3,4,5,6,7,8,9,10};

在这里插入图片描述

#include <stdio.h>
int main()
{
	int arr[10]={1,2,3,4,5,6,7,8,9,10};
	int *p=&arr[0];
	int i=0;
	for(i=0;i<10;i++)
	{
		printf("%d ",*(p+i));
	}
	return 0;
}

4.2 指针 - 指针

#include <stdio.h>
int strlen1(char *s)
{
	char *p=s;
	while(*p!='\0')
	{
		p++;
	}
	return p-s;
}
int main()
{
	printf("%d\n",strlen1("abcdef"));
	return 0;
}

4.3 指针的关系运算

#include <stdio.h>
int main()
{
	int arr[10]={1,2,3,4,5,6,7,8,9,10};
	int *p=arr;
	while(p<arr+10){
		printf("%d ",*p);
		p++;
	}
	return 0;
}

5.野指针

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

5.1 野指针成因

  • 指针未初始化
  • 指针越界访问
  • 指针指向的空间释放

5.2 如何规避野指针

5.2.1 指针初始化

如果明确知道指针指向哪里就直接赋值地址,如果不知道,可以个指针赋值NULL
NULL是C语言中定义的一个标识符常量,值是0,0也是地址,这个地址是无法使用的

int num=10;
int *p1=&num;
int *p2=NULL;
5.2.2 小心指针越界

一个程序申请了那些空间,通过指针也只能访问那些空间,不能超出访问的范围

6.数组名的理解

  • 数组名就是数组首元素的地址
  • sizeof(数组名)sizeof中单独放数组名,表示整个数组,计算的是整个数组的大小,单位是字节
  • &数组名,这里的数组名表示整个数组,取出的是整个数组的地址

7.使用指针访问数组

#include <stdio.h>
int main()
{
	int arr[10]={0};
	//输入
	int i=0;
	int *p=arr;
	for(i=0;i<10;i++)
	{
		scanf("%d",p+i);
	}
	//输出
	for(i=0;i<10;i++)
	{	
		printf("%d ",*(p+i));
	}
	return 0;
}

8.二级指针

指针也是变量,是变量就有地址,指针变量的地址存放在二级指针中
在这里插入图片描述
二级指针跟一级指针用法类似

  • 24
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值