C语言|指针进阶(1):字符指针、指针数组、数组指针

目录

🍎指针的概念:

🍎1.字符指针

🍌列1:

🍌列2:

✍内存展示 

🍎2.指针数组

🍌代码:

🍌内存原理:

✍*(parr[i] + j)

✍*(*(parr+i) + j))

🍎3.数组指针

🍌3.1数组指针的定义

✍注意:

✍练习:

🍌3.2&数组名和数组名

✍数组名不是首元素地址的情况

✍思考题

🍌3.3.数组指针的使用

✍代码

✍原理图: 

✍识别代码

✍int (*parr3[10])[5];

🍎总结


指针对于C语言而言是至关重要的,下面是我学习指针的一些学习路线和个人想法,写的不好,希望各位大佬不吝指教。

🍎指针的概念:

  1. 指针就是变量,用来存放地址,地址唯一标识一块内存空间。

  2. 指针的大小是固定的4/8个字节(32位平台/64位平台)。

  3. 指针是有类型,指针的类型决定了指针的+-整数的步长,指针解引用操作的时候的权限。

  4. 指针的运算

🍎1.字符指针

常量字符串放在只读,代码段

🍌列1:

int main()
{
	const char* p = "abcdef";//"abcdef"为常量字符串
	printf("%s\n", p);
    //p为常量字符串首元素的地址,打印的为字符串格式(%s),会沿着首地址打印,直到遇到'\0'
	printf("%c\n", p);
    //p为指针变量,为地址,无法根据地址打印字符
	printf("%c\n", *p);
    //*p==a,%c打印一个字符,打印a
	printf("%s\n", *p);
    //*p==a,%s为沿字符串首地址打印字符串,直到遇到‘\0’,此时无法打印

	return 0;
}

🍌列2:

int main()
{
	char* p1 = "abcdef";//常量字符串不能修改,p1,p2只存储了一份,指向同一块空间的存储位置
	char* p2 = "abcdef";

	if (p1 == p2)
	{
		printf("p1==p2");
	}
	else
	{
		printf("haha");
	}

	return 0;
}

  •  判断字符串是否相等使用strcmp函数,==是判断地址是否相等的

✍内存展示 

🍎2.指针数组

本质是数组,用来存放指针

int* arr1[10];//整形指针数组——存放整形变量的地址
char* arr2[4];//一级字符指针数组——存放字符变量的地址
char** arr3[5];//二级字符指针数组——可存放一级字符指针的数组
  • 指针变量\数组在一定情况下可以存放整形变量的值,它的空间是可以存放的,但在C的语法中是不正确的

🍌代码:

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

	return 0;
}

🍌int* parr[]内存原理:

✍*(parr[i] + j)

✍*(*(parr+i) + j))

🍎3.数组指针

🍌3.1数组指针的定义

  • 数组指针是指针,它存放数组地址,而非指向数组本身

整形指针: int * pint; 能够指向整形数据的指针。 浮点型指针: float * pf; 能够指向浮点型数据的指针。

数组指针:指向数组的指针

int *p1[10];
int (*p2)[10];
//p1, p2分别是什么?

int (*p)[10]; //解释:p先和结合,说明p是一个指针变量,然后指着指向的是一个大小为10个整型的数组。所以p是一个 指针,指向一个数组,叫数组指针。 //这里要注意:[]的优先级要高于号的,所以必须加上()来保证p先和*结合

✍注意:

数组指针可以利用二级指针的方式获得数组内的值,但是不可以使用二级指针的方式接收数组指针

 

  • 不能用二级指针接收数组指针

 

✍练习:

 int main()
 {
     char arr[5] = { 1,2,3,4,5 };
     char(*p1)[5] = &arr;
     //(*p1)表示指针,指向数组arr的地址,[5]表示指针所指向的5个元素,int表示数组的练习
     
     return 0;
 }

  •  *p1的类型为int [5],相当于将一维数组的数组名取出后的类型

🍌3.2&数组名和数组名

int main()
 {
     int arr[10] = { 0 };
     printf("arr = %p\n", arr);
     printf("&arr = %p\n", &arr);
 ​
     printf("arr+1 = %p\n", arr + 1);
     printf("&arr+1 = %p\n", &arr + 1);
 ​
     return 0;
 }

&arr表示的是数组的地址,所以+1后直接跳过了整个数组的。

arr表示首元素的地址

但它们指向相同的地址

✍数组名不是首元素地址的情况

  1. &数组名

  2. sizeof(数组名):在sizeof内数组名必须单独出现

✍思考题

int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int(*pa)[10] = &arr;//数组指针
	//pa为数组&arr,(*pa)为arr数组首元素的地址,pa为指针变量
	
	//方法1
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", (*pa)[i]);
        //pa为数组&arr,(*pa)为arr,相当于arr[i]
	}
	printf("\n");

	//方法2
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", *(pa + i));
        //pa为数组的地址,每次多加1,相当于地址增大一个arr数组的大小
	}
	printf("\n");

	//方法3
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", *pa + i);
        //*pa=arr,每次加1,地址增加一个整形的大小,打印出的是地址
	}
	printf("\n");

	//方法4
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", *(*pa + i));
        //数组arr的地址由pa接收,表面在这个条件下,可以指针变量可以经历两次解引用
        //第一次解引用为数组的地址解引用,获得首元素的地址
        //第二次首元素的地址解引用,获得该地址指向的空间内的值
        //由方法3得,(*pa+i)是arr数组中元素得地址,通过再次解引用得到各元素值
	}
	printf("\n");

	return 0;
}

🍌3.3.数组指针的使用

  • 数组指针在二维数组应用中常见

✍代码

void print1(int arr[3][5], int row, int col)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			printf("%d ", arr[i][j]);
		}
		printf("\n");
	}
}

void print2(int(*p)[5], int row, int col)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
            //printf("%d ", p[i][j]);
			printf("%d ", *(*(p+i)+j));
            //*(p+i)==p[i]
            //*(*(p+i)+j)==p[i][j]
		}
		printf("\n");
	}
}

int main()
{
	int arr[3][5] = { {1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7} };
	//数组名arr,为首元素的地址
	//但是二维数组的首元素是二维数组的第一行
	//所以这里传递的arr,其实相当于第一行的地址,是一维数组的地址
	//可以用数组指针接收
	print1(arr, 3, 5);
    printf("\n");
	print2(arr, 3, 5);

	return 0;
}

✍数组指针原理图: 

✍识别代码

int arr[5];//一维数组
int *parr1[10];//指针数组
int (*parr2)[10];//数组指针
int (*parr3[10])[5];//用来存放数组指针的数组

✍int (*parr3[10])[5];

🍎总结

  1. 个人认为指针的难度在于它在内存间的不断调换
  2. 要想学好指针,需要多画图,多尝试,多调试,看看它的内存是则么变化的
  3. 这一篇博客是c语言指针进阶的基础,后边的内容是这篇的衍生,将这里的内容理解后,后边会很好理解。
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

榶曲

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值