指针初识~~

指针定义

指针即地址,
int* p=&a;
我们用指针变量p保存a的地址,形象的称为p指向a。
指针有两个值:自身的值p,指向的值*p。(或者说还有一个值 &p,自己的地址,用二级指针**q保存)
定义时将 int * 写在一块,便于区分和理解。
int *;自身类型
int ;指向类型

#include<stdio.h>
int main()
{
	int a = 10;
	int* p = &a;//p指向a
	int * q = p;//q也指向a,把p存的值给了q,p保存的是a的地址
	int * w = &p;//“初始化”:“int *”与“int **”的间接级别不同
	//C语言在此不会报错,C语言类型检查不严格,若文件为cpp则会报错,类型不匹配
	return 0;
}

通过指针交换变量的值

#include<stdio.h>
void swap(int* a, int* b)//形参a,b指向了实参变量,通过指针解引用赋值修改,达到对实参变量的交换
{
	int temp = *a;
	*a = *b;
	*b = temp;
}
/*
错误写法:
int* temp=a;
     a=b;
     b=temp;
	 这是将a,b实参的地址交换 v 
*/
int main()
{
	int a = 10;
	int b = 20;
	printf("a=%d b=%d\n", a, b);
	swap(&a, &b);
	printf("a=%d b=%d\n", a, b);
	return 0;
}

指针变量所占字节数都是4,不论是什么类型的指针。(32位操作系统下,64位下为8个字节)
因为指针变量要保存的是地址,32位下地址0~2^32,申请的地址是任意的,要能对所有产生的地址都能保存所以需要四个字节,一个字节八位。
指针的类型决定了解引用时访问的字节数,以及对指针加一时增加的字节数,类型决定步长。

指针操作

指针可以进行那些操作:
赋值:把地址赋给指针
解引用:*获得指向地址上存储的值
取址(三声):获取自己的地址
和整数相加减:+n会增加(n *sizeof(type))字节
自增自减
相减:指针减指针(不能指针加指针)
比较:可以比较,充当循环结束条件。

#include<stdio.h>
#include<assert.h>
int main()
{
	char* str = NULL;
	assert(str != NULL);//断言 判断  debug时才有用
	
	return 0;
}


/*
int main()
{
	float values[5];
	float* vp;
	for (vp = &values[0]; vp < &values[5];)//指针之间可以通过比较关系来达到条件约束
		*vp++ = 0;
	return 0;
}
*/

指针常量与常量指针

在这里插入图片描述

int main()
{
	int a = 10;
	int b = 20;
	const int* p = &a;//看const修饰的是p还是*p
	/*
	const int *p//封锁*p,即封锁指向的值,不能通过指向改变值的内容,即不能通过*p 修改a
	int * const p//const 封锁p的值不能修改 不可以p=&a,封锁指向
	const int * const p
	*/
	p = &b;
	//*p = 100;
	return 0;
}

指针数组,数组指针

指针数组,是一个数组,存的元素时指针。int* brr[3]={&1,&b,&c}; 元素类型为int*
数组指针,是一个指针,指向一个数组。int (*brr)[3];brr指向一个int型数组

野指针

#include<stdio.h>
int* test();
int main()
{
	//int a = 10;//在内存中开辟一块空间
	//&a;//a的地址
	//int* p = &a;//用指针变量保存a的地址,sizeof(p)= 4,(64位操作系统为8)

	printf("%d\n", sizeof(char*));
	printf("%d\n", sizeof(short*));
	printf("%d\n", sizeof(int*));
	printf("%d\n", sizeof(double*));
	/*都是4*/
	int a = 0x11223344;
	int* pa = &a;
	//*pa = 0;//通过地址pa访问a的内容
	char* pc = &a;//这里赋值是没有问题的
	*pc = 0;//这里只会修改一个字节的内容 Ox11223300
	/*
	指针类型决定了指针进行解引用时,能够访问的空间大小
	int* 4个字节
	char* 1个字节
	double* 8个字节
	*/
	/*指针类型决定了指针的步长*/
	printf("%p\n", pa);//0072FE54
	printf("%p\n", pa + 1);//0072FE58   +1跳过四个字节,步长4
	printf("%p\n", pc);//0072FE54
	printf("%p\n", pc + 1);//0072FE55
	int arr[10] = { 0 };
	int* p = arr;//数组名——首元素地址
	for (int i = 0; i < 10; ++i)
	{
		*(p + i) = 1;
	}
	for (int i = 0; i < 10; ++i)
		printf("%d ", *(p + i));
	printf("\n");
	int size = (p+1)-p;
	char* p2 = arr;
	for (int i = 0; i < 10; ++i)
	{
		*(p2 + i) = 0;//0 0 0 1 1 1 1 1 1 1只改了前三位,因为这里按逐个字节修改,总共改10个字节,int3个有12位,因为这里是1,所以对于第三个数的前两位修改就会使1变0
	}
	for (int i = 0; i < 10; ++i)
		printf("%d ", *(p + i));
	printf("\n");
	//int* p3;//野指针:指向位置不可知(随机,错误,无限制)
	//*p3 = 20;//不知会把那个内存位置的值修改了
	//没有初始化和数组越界访问都会造成野指针
	int* p4 = test();/*指针指向已经释放的内存*/
	*p = 20;
	
	return 0;
}
int* test()
{
	int a = 10;//函数执行完毕a的内存就会被释放,所以下面返回的内存已被释放
	return &a;
}

使用指针常用来传参,得到返回值,return只能返回一个值,使用指针可以再函数中操作实参,修改实参。对数组操作只能传指针,但有时不想数组被修改,只读权限,可以再传参时加const

int sum(const int* a,int n)
这里可以通过常量指针来理解,const封锁*p,即不可以通过指针来修改它所指向的值
不能把const数组的地址给普通指针

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值