本章重点
1. 字符指针
2. 数组指针
3. 指针数组
4. 数组传参和指针传参
5. 函数指针
6. 函数指针数组
7. 指向函数指针数组的指针
8. 回调函数
9. 指针和数组面试题的解析
在C语言初阶中,对指针友友们应该有了一定的了解:
1. 指针就是个变量,用来存放地址,地址唯一标识一块内存空间。(内存会被划分为以字节为单位的空间,每个空号间都有一个编号(地址、指针),地址需要 空间被存起来,这个空间就是指针变量)
2. 指针的大小是固定的4/8个字节(32位平台/64位平台)。(硬件 CPU 要么支持32位的虚拟空间地址,要么支持64位的虚拟空间地址,32位的虚拟空间地址提供32bit位的地址,64位的虚拟空间地址提供64bit的地址)(我们平常打印的地址是虚拟地址,CPU产生虚拟地址,通过虚拟地址找到物理地址,进而找到内容)
3. 指针是有类型,指针的类型决定了指针的+-整数的步长,指针解引用操作的时候的权限。
4. 指针的运算。
接下来让我们再进一步的了解指针!!!
一 字符指针
在指针的类型中我们知道有一种指针类型为字符指针 char* 。
1. #include <stdio.h> 2. int main() 3. { 4. char ch = 'w'; 5. char* p = &ch; 6. 7. char* pa = "abcdefg";//"abcdefg"储存在内存的只读存储区,只能读 该字符串有一个起始地址,也就是a的地址,pa存的就是a的地址 8. *pa = 'w';//这种情况是会报错的,a不能改变为w。 9. //所以我们一般写成const char* pa = "abcdefg" 10. return 0; 11. }
上图中两个圈圈是不同的,"abcdefg"储存在内存的只读存储区,只能读 该字符串有一个起始地址,也就是a的地址,pa存的就是a的地址
注意:所以我们一般写成const char* pa = "abcdefg"
一道笔试题
代码展示:
1. #include <stdio.h> 2. int main() 3. { 4. char str1[] = "hello bit."; 5. char str2[] = "hello bit."; 6. const char* str3 = "hello bit."; 7. const char* str4 = "hello bit."; 8. if (str1 == str2) 9. printf("str1 and str2 are same\n"); 10. else 11. printf("str1 and str2 are not same\n"); 12. if (str3 == str4) 13. printf("str3 and str4 are same\n"); 14. else 15. printf("str3 and str4 are not same\n"); 16. return 0; 17. }
arr1和arr2代表内存中两个不同的空间,所以数组首元素地址是不相等的,而'hello world'是一个常量表达式,arr3和arr4里面存放的地址是同一个,都是h的地址,所以是一样的。
代码展示:
1. #include <stdio.h> 2. int main() 3. { 4. int a, b;//a int类型 b int类型 5. int* pa, pb;//pa int*类型 pb int类型 6. int* pa, *pb;//pa pb都是int*类型,可以共用一个int,但是不能共用一个* 7. typedef int* pint;//将int*重新起了个名字,叫pine; typedef将一个自己命名的类型用已经有的类型来代替 8. pint pa, pb;//在这里,pa,pb都是int*类型 9. 10. return 0; 11. }
typedef将一个自己命名的类型来代替已经有的类型
二 指针数组
在C语言初阶专栏里的指针中,友友们对指针数组肯定有了一定的了解,指针数组是一个存放指针的数组。
#include <stdio.h>
int main()
{
int arr1[3];//整形的数组 存放整形的数组 int int int
int* arr2[3];//整形指针的数组 存放整形指针的数组 int* int* int*
char* arr2[3]; //一级字符指针的数组 存放字符指针的数组 char* char* char*
char** arr3[3];//二级字符指针的数组 存放二级字符指针的数组 char** char** char**
return 0;
}
打印字符串,有首元素地址,就可以打印
代码展示:
1. #include <stdio.h> 2. int main() 3. { 4. char* arr[] = { "abcd", "efgh", "igkl" };//arr[],分别存放a,e,i的地址,也分别是字符串首元素地址 5. int sz = sizeof(arr) / sizeof(arr[0]);//计算有多少个char* 6. int i = 0; 7. for (i = 0; i < sz; i++) 8. { 9. printf("%s ", arr[i]); 10. } 11. return 0; 12. }
浅说一下数组,arr[5],arr是首元素的地址,首元素地址后面跟一个下标,就可以打印数组的每一个元素
1. #include <stdio.h> 2. int main() 3. { 4. int arr1[5] = { 1,2,3,4,5 }; 5. int arr2[5] = { 2,3,4,5,6 }; 6. int arr3[5] = { 3,4,5,6,7 }; 7. int* arr[] = { arr1, arr2, arr3 }; 8. int sz = sizeof(arr) / sizeof(arr[0]); 9. int i = 0; 10. for (i = 0; i < sz; i++) 11. { 12. int j = 0; 13. for (j = 0; j < 5; j++) 14. { 15. printf("%d ", arr[i][j]);//arr[i] 是数组首元素地址//*((*(arr+i))+j) 16. } 17. printf("\n"); 18. } 19. return 0; 20. }