C语言之指针详解(1)

目录

本章重点
1. 字符指针
2. 数组指针
3. 指针数组
4. 数组传参和指针传参
5. 函数指针
6. 函数指针数组
7. 指向函数指针数组的指针
8. 回调函数
9. 指针和数组面试题的解析
大家对比前面C语言之指针初阶来看,指针进阶明显看起来难度大了很多,但是我们需要有迎难而上的勇气
指针的主题,我们在初级阶段的《指针》章节已经接触过了,我们知道了指针的概念:
1. 指针就是个变量,用来存放地址,地址唯一标识一块内存空间
2. 指针的大小是固定的4/8个字节(32位平台/64位平台)
3. 指针是有类型,指针的类型决定了指针的+-整数的步长,指针解引用操作的时候的权限
4. 指针的运算
1. 字符指针
在指针的类型中我们知道有一种指针类型为字符指针 char*
我们来看代码
#include<stdio.h>
int main()
{
	char arr[] = "abcdef";
	char* pc = arr;
	printf("%s\n", arr);
	printf("%s\n", pc);
	return 0;
}

为什么打印的结果是一样的呢?首先把一个字符串存放到字符数组里面,数组名赋给pc,pc就相当于指向那个字符数组,所以打印的内容是一样的

我们再看下一个代码

#include<stdio.h>
int main()
{
	char* p = "abcdef";//"abcdef"是一个常量字符串,这里相当于把字符串首元素的地址a放到了p当中,我们打印出来看效果
	printf("%s\n", p);
	return 0;
}

我们接着看代码

#include<stdio.h>
int main()
{
	char* p = "abcdef";//"abcdef"是一个常量字符串,这里相当于把字符串首元素的地址a放到了p当中,我们打印出来看效果
	*p = 'w';
	printf("%s\n", p);
	return 0;
}

既然我是常量字符串就不能被修改,大家理解一下,是不是只有变量才有被修改的可能

上述代码就报错了,希望大家能够理解,这种代码一律不能被修改,这是当我们联想一下const,我们来看代码

这样我们就完全把这个字符串限制死了,不能被修改

#include<stdio.h>
int main()
{
	const char* p = "abcdef";//"abcdef"是一个常量字符串,这里相当于把字符串首元素的地址a放到了p当中,我们打印出来看效果
	*p = 'w';
	printf("%s\n", p);
	return 0;
}

来看下面代码

#include<stdio.h>
int main()
{
	char arr1[] = "abcdef";
	char arr2[] = "acbdef";
	char* p1 = "abcdef";
	char* p2 = "abcdef";
	if (arr1 == arr2)
	{
		printf("hehe\n");
	}
	else
	{
		printf("haha\n");
	}
	return 0;
}

打印haha,希望大家能理解,但是大家仔细看一看下一个代码呢

#include<stdio.h>
int main()
{
	char arr1[] = "abcdef";
	char arr2[] = "acbdef";
	char* p1 = "abcdef";
	char* p2 = "abcdef";
	if (*p1 == *p2)
	{
		printf("hehe\n");
	}
	else
	{
		printf("haha\n");
	}
	return 0;
}

但是最好的方法是在char*前面加一个const避免被修改

#include<stdio.h>
int main()
{
	char arr1[] = "abcdef";
	char arr2[] = "acbdef";
	const char* p1 = "abcdef";
	const char* p2 = "abcdef";
	if (*p1 == *p2)
	{
		printf("hehe\n");
	}
	else
	{
		printf("haha\n");
	}
	return 0;
}

我们接着看代码

#include<stdio.h>
int main()
{
	int arr[10] = { 0 };//整型数组
	char ch[5] = { 0 };//字符数组
	int* parr[4];//存放整型指针的数组--指针数组
	char* pch[5];//存放字符指针的数组--指针数组
	return 0;
}

解释附在代码后面的了,希望大家能够理解,我们再来看下列代码

#include<stdio.h>
int main()
{
	int a = 10;
	int b = 20;
	int c = 30;
	int d = 40;
	int* arr[4] = { &a,&b,&c,&d };
	int i = 0;
	for (i = 0; i < 4; i++)
	{
		printf("%d ", *(arr[i]));
	}
	return 0;
}

虽然我们打印出来了结果,但是这不是指针数组的本质用法,我们来看下列优化过的代码

#include<stdio.h>
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 };
	int i = 0;
	for (i = 0; i < 3; i++)
	{
		int j = 0;
		for (j = 0; j < 5; j++)
		{
			printf("%d ", *(parr[i] + j));
		}
		printf("\n");
	}
	return 0;
}

指针数组里面存放的是各个数组的首元素的地址,地址加依次1解引用操作得到后面的数据,就得到了一个二维数组,这就是指针数组的正常操作方式,希望大家能够理解

下一节我们讲解数组指针

猜你喜欢

转载自blog.csdn.net/fjj2397194209/article/details/131217068