C语言学习笔记——指针章节

学习小结

c语言指针学习笔记汇总

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>

//指针
//在计算机科学中,指针是编程语言的一个对象,利用地址,它的值直接指向存在电脑存储器中另一个地方的值
//在 C/C++语言中,指针一般被认为是指针变量
//指针变量的内容存储的是其指向的对象的首地址
//int main()
//{
//	int a = 10;
//	int* p = &a;//指针变量
//	//存放地址的变量也被称为指针变量
//	return 0;
//}
//注意:指针大小在32位平台是4个字节,64位平套是8个字节

//指针和指针类型
//意义
//int main()
//{
//	//因为是64位平台,所以一下内存是是八个字节
//	//printf("%d\n", sizeof(char*)); //8
//	//printf("%d\n", sizeof(short*)); //8 
//	//printf("%d\n", sizeof(int*)); //8
//	//printf("%d\n", sizeof(double*)); //8
//	int a = 0x11223344;
//	//int* pc = &a;
//	//*pc = 0;
//	//char* pa = &a;
//	//*pa = 0; 
//	//printf("%p\n", pc); //00000038A96FFA14
//	//printf("%p\n", pa); //00000038A96FFA14  “初始化”: 从“int *”到“char *”的类型不兼容
//	return 0;
//}
//指针类型决定了指针进行解引用操作的时候能够访问空间的大小

//int main()
//{
//	int a = 0x11223344;
//	int* pa = &a;
//	char* pc = &a;
//	printf("%p\n", pa); //000000E2177BF814
//	printf("%p\n", pa+1); //0000009AC57AF558
//
//	printf("%p\n", pc); //000000E2177BF814
//	printf("%p\n", pc+1); //0000009AC57AF555
//	return 0;
//}
//指针类型决定了:指针向前或者向后走一步走多远(指针的步长) 单位是字节
//int main()
//{
//	int arr[10] = { 0 };
//	int* p = arr;//数组名是首元素的地址
//	int i = 0;
//	for (i = 0; i < 10; i++)
//	{
//		*(p + i) = 1;
//	}
//	return 0;
//}
//总结:指针的类型决定了,对指针解引用的时候有多大的权限(能操作几个字节)

//野指针
//int main()
//{
//	int a;//局部变量不初始化的时候,默认的是随机值
//	int* p;//因为没有初始化,所以这个局部变量指针里面放的是随机的地址
//	return 0;
//}
//指针越界访问
//int main()
//{
//	int arr[10] = { 0 };
//	int* p = arr;
//	int i = 0;
//	for (i = 0; i < 12; i++)//因为只有10个元素,所以超出访问
//	{
//		p++;//当指针指向的空间超出数组arr的范围时,p就是为野指针
//	}
//	return 0;
//}
//指针指向的空间被释放
//int* test()
//{
//	int a = 10;
//	return &a;
//}
//int main()
//{
//	int* p=text();
//	*p = 20;
//	return 0;
//}
//int main()
//{
//	//未初始化的指针变量
//	int* p;//局部变量不初始化,里面默认放的是一个随机值
//	*p = 20;
//	return 0;
//}
//数组越界导致的野指针问题
//int main()
//{
//	int a[10] = { 0 };
//	int i = 0;
//	int* p = a;//此时p里面存的是首元素的地址
//	for (i = 0; i < 12; i++)//此时越界访问了
//	{
//		*p = i;
//		p++;
//	}
//	return 0;
//}
//int main()
//{
//	int* p = NULL;//当不知道一个指针变量该初始化什么时,必须赋予一个空指针null
//	//NULL 是用来初始化空指针的,给指针赋值的
//	return 0;
//}
//int main()
//{
//	int a = 10;
//	int* p = &a;
//	printf("%d\n", a);
//	*p = 20;
//	printf("%d\n", a);
//	p = NULL;
//	//*p = 30;//因为已经把p这个指针改为空指针,所以此代码会发生冲突
//	return 0;
//}

//指针运算
//指针+-整数
//指针-指针
//指针的关系运算(比大小)

//1、指针加减整数
//通过指针访问数组中的元素
//加法
//int main()
//{
//	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
//	int i = 0;
//	int sz = sizeof(arr) / sizeof(arr[0]);
//	int* p = arr;//数组名就是首元素的地址
//	for (i = 0; i < sz; i++)
//	{
//		printf("%d ", *p);
//		p++;
//	}
//	return 0;
//}
//减法
//int main()
//{
//	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
//	int i = 0;
//	int sz = sizeof(arr) / sizeof(arr[0]);
//	//因为是减法,所以倒着来
//	int* p = &arr[9];
//	for (i = 0; i < sz; i++)
//	{
//		printf("%d ", *p);
//		p--;
//	}
//	return 0;
//}

//2、指针减指针(地址减地址)
//注意指针相减时必须要指向同一个空间的
//int main()
//{
//	char ch[5] = { 0 };
//	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
//	printf("%d\n", &arr[9] - &arr[0]);//9
//	//由此可见地址是有大小的
//	//printf("%d\n", &arr[9] - &ch[0]);//没意义
//	return 0;
//}

//用指针减指针的方式实现strlen求字符串长度的函数
//int my_strlen(char* x)
//{
//	char* start = x;
//	char* end = x;
//	while (*end != '\0')
//	{
//		end++;
//	}
//	return end - start;//元素个数
//}
//int main()
//{
//	//strlen - 求字符串长度
//	//
//	char arr[] = "bit";
//	int len = my_strlen(arr);
//	printf("%d\n", len);
//	return 0;
//}

//3、指针的关系运算(比大小)

//指针和数组
//数组名是首元素的地址
//int main()
//{
//	int arr[10] = { 0 };
//	printf("%p\n", arr);     //0000000B6050FAE8
//	printf("%p\n", arr+1);   //0000000B6050FAEC
//
//	printf("%p\n", &arr[0]); //0000000B6050FAE8
//	printf("%p\n", &arr[0]+1);//0000000B6050FAEC
//
//	printf("%p\n", &arr);   //0000000B6050FAE8
//	printf("%p\n", &arr+1); //0000000B6050FB10
//	//有两个例外
//	//1、&arr 取地址数组名的时候,这个时候数组名不是首元素的地址,此时表示整个数组的地址
//	//2、sizeof(arr) sizeof(数组名),此时此刻数组表示的是整个数组在内存中的大小
//	return 0;
//}
//数组是可以通过指针进行访问的
//int main()
//{
//	int arr[10] = { 0 };
//	int* p = arr;
//	int i = 0;
//	//for (i = 0; i < 10; i++)
//	//{
//	//	printf("%p == %p\n", p + i, &arr[i]);
//	//}
//	for (i = 0; i < 10; i++)
//	{
//		*(p + i) = i;//指针的形式将值放进去
//		printf("%d ", arr[i]);//数组的形式将放进去的值打印出来
//	}
//	return 0;
//}
//000000261F73F5E8 == 000000261F73F5E8
//000000261F73F5EC == 000000261F73F5EC
//000000261F73F5F0 == 000000261F73F5F0
//000000261F73F5F4 == 000000261F73F5F4
//000000261F73F5F8 == 000000261F73F5F8
//000000261F73F5FC == 000000261F73F5FC
//000000261F73F600 == 000000261F73F600
//000000261F73F604 == 000000261F73F604
//000000261F73F608 == 000000261F73F608
//000000261F73F60C == 000000261F73F60C

//二级指针
//int main()
//{
//	int a = 10;
//	int* pa = &a;//pa就是一级指针变量,int* 就是一级指针类型
//	int** ppa = &pa;//将pa的地址放到ppa里面,此时ppa就是二级指针变量,int** 就是二级指针类型
//	int*** pppa = &ppa;//三级指针
//	printf("%d\n", **ppa);//10
//	**ppa = 20;
//	printf("%d\n", **ppa);//20
//	printf("%d\n", a);//20
//	return 0;
//}

//指针数组 - 本质上是一个数组 - 存放指针的数组
//数组指针 - 本周上是一个指针
//int main()
//{
//	int a = 10;
//	int b = 20;
//	int c = 30;
//	//int* pa = &a;
//	//int* pb = &b;
//	//int* pc = &c;
//	int* arr[3] = { &a,&b,&c };//指针数组
//	int i = 0;
//	for (i = 0; i < 3; i++)
//	{
//		printf("%d ", *(arr[i])); //10 20 30
//	}
//	return 0;
//}

以上代码均在vs2022环境下编译

猜你喜欢

转载自blog.csdn.net/qq_72935001/article/details/126131322