目录
本章重点
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解引用操作得到后面的数据,就得到了一个二维数组,这就是指针数组的正常操作方式,希望大家能够理解
下一节我们讲解数组指针