指针是什么
内存—>内存的单元(1byte)—>编号 —>地址—–>指针
多以指针就是一个地址而已
口头语说的指针其实是指针变量
指针变量就是一个变量而已,就是一块空间,指针变量用来存放空间
# include <stdio.h>
int main()
{
in a = 10;
int* pa = &a; // 指针变量pa,类型是int*
printf("%d\n", a);
char ch = 'w';
char* pc = &ch; // 指针变量的类型是char*
}
指针变量的大小? 4/8 取决于计算机是32位还是64位。
指针类型决定了解引用操作是的权限,以及+1-1操作时跳过几个字节。
指针的运算
1、±整数
2、指针-指针
3、指针关系的运算
指针数组:本质上就是数组,数组中存放的是指针(地址)
数组名
1、数组名在大部分情况表示:数组首元素的地址
但是有两个例外:
a) sizeof(数组名)
b) &数组名
2、&数组名 取出的是数组的地址
数组指针
int main()
{
int arr[10] = {1,2,4};
int (*parr)[10] = &arr; // 数组指针 指向数组的指针
return 0;
}
函数指针
# include <stdio.h>
int Add(int x, int y)
{
return x + y;
}
int main()
{
int(*pf)(int ,int ) = &Add; // 函数指针, 或者Add
// 函数的的地址存放到函数指针变量中
int ret = (*pf)(2,3); // 或者pf(2,3)
printf("%d\n", ret);
return 0;
}
函数指针数组
存放函数指针的数组
# include<stdio.h>
int main()
{
int(*pfarr[4])(int ,int ) = &Add;
return 0;
}
回调函数
通过函数指针调用的函数就是回调函数
qsort —- 使用冒泡排序的思想,模拟实现一下qsot
-
qsort怎么使用。
-
知道qsort怎么使用回调函数实现的通用的排序。
# include <stdio.h> int Cmp(const void* e1, const void* e2) { return *(int*)e1 - *(int*)e2; } void Swap(char* buff1, char* buff2, int width) { int i = 0; for (i = 0; i < width; i++) { char temp = *buff1; *buff1 = *buff2; *buff2 = temp; buff1++; buff2++; } } void bobble_sort(void* base, int sz, int width, int(*cmp)(const void* e1, const void* e2)) { int i = 0; for (i = 0; i < sz-1; i++) { int flag = 1; // 假设数组是排好序的 int j = 0; for (j = 0; j < sz - 1 - i; j++) { if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) > 0) { Swap((char*)base + j * width, (char*)base + (j + 1) * width, width); flag = 0; } } if (flag == 1) { break; } } } void test4() { int arr[] = { 2,6,3,7,4,8,5,9,0 }; int sz = sizeof(arr) / sizeof(arr[0]); bobble_sort(arr, sz, sizeof(arr[0]), Cmp); for (int i = 0; i < sz; i++) { printf("%d ", arr[i]); } } int main() { test4(); return 0; }
指针+结构体+动态内存管理很重要
笔试题详解
数组名的理解,指针的运算和指针类型的意义
# include <stdio.h>
int main()
{
int a[] = {1,2,3,4};
printf("%d\n", sizeof(a)); // 16
// sizeof(数组名), 数组名表示的是整个数组,计算的是整个数组的大小,单位是字节。
printf("%d\n", sizeof(a+0)); // 4 ,a没有单独放在sizeof的内部,也没有取地址,所以a在这里表示数组首元素的地址。
printf("%d\n", sizeof(*a)); // 4 a是首元素的的地址,*a等价与首元素,首元素的大小为4个字节
// *a中的a是数组首元素的地址
printf("%d\n", sizeof(a+1)); // 4/8 a+1是第二个元素的地址
printf("%d\n", sizeof(a[1])); // 4 是第二个元素的大小
printf("%d\n", sizeof(&a)); // 4/8 取出的是整个数组的地址,也就是个地址
printf("%d\n", sizeof(*&a)); // 16 *&可以抵消,剩下sizeof(a) 或者 &a拿到的是数组的地址,类型是int(*)[4],数组指针解引用找到是数组
printf("%d\n", sizeof(&a+ 1)); // 4/8 &a--->int(*)[4]
// &a+1 是从数组a的地址向后跳过了一个(4个整型元素的)数组的大小, &a+1还是地址,是地址就是4/8个字节
printf("%d\n", sizeof(&a[0] + 1)); // 4/8 第二个元素的地址
return 0;
}