赞
踩
指针的概念
地址表示内存单元的编号,也被称为指针。指针既是地址,也是一种专门用于处理地址数据的数据类型。
例如,变量a的地址或者十六进制表示的0x1000都可以视作指针。
指针变量的定义
语法:基类型 * 指针变量名。
基类型可以是之前学过的各种数据类型,如整型、浮点型、字符型、结构体类型、函数类型等,它表示指针所指向的内存空间能够存放的数据类型。例如:int *p; 中,p就是一个指向整型数据的指针变量。
*在定义时表示定义的是指针类型的变量。
指针变量名需符合标识符命名规则。
指针类型
例如:在int *p;中,int *整体被称为指针类型,表示指向整型数据的指针类型。
指针变量的引用
例如:int a = 10; int *p = &a; ,p指向 a 。
*是指针运算符,为单目运算,运算对象只能是指针(地址)。
*p表示访问 p 所指向的基类型的内存空间,这是一种间接访问。其过程包括:首先拿出 p 中的地址,在内存中定位;然后偏移出 sizeof(基类型) 大小的一块空间;最后将偏移出的这块空间当作一个基类型变量来看。
例如,*p 的运算效果相当于直接访问的变量 a 。
类似地,对于int a; ,a的数据类型是 int ,&a的数据类型是 int* ,对于 float b; ,&b的数据类型是 float* 。
指针变量的初始化
如果指针变量没有初始化,此时的值是随机值(野指针)。
初始化可以让指针变量有明确的指向,例如:int a; int *p = &a; 或者 int *p = NULL(NULL 表示空指针,即 0 号地址)。
赋值
例如:int *p; p = &a;
定义多个指针变量
例如:int *p, *q; 表示定义了两个指针变量。
注意:定义时候的 * 是修饰变量名的,表示定义的是一个指针类型的变量。
为什么需要指针指针
指针可以实现被调函数修改主调函数中的数据。
1、形参是指针类型的变量,用来接收实参(实参是要操作的内存空间的地址)。
2、实参:要修改谁,就把谁的地址传进去,但要保证空间有效。
3、注意:被调函数中一定要有*p的运算(间接访问的操作)。
4、值传递只是实参数据赋值给了形参,而地址(指针传递)传递的是地址,可以实现被调修改主调。
练习:
- #include <stdio.h>
-
- // 函数:实现两个数相加,并将结果存储在指针所指的变量中
- void ADD(int *a, int b)
- {
- *a = *a + b; // 将指针 a 所指变量的值与 b 相加,并将结果存储回指针所指的变量
- }
-
- // 函数:找出两个数中的最大值和最小值,并通过指针返回
- void maxandmin(int a, int b, int *max, int *min)
- {
- *max = a > b? a : b; // 如果 a 大于 b,将 a 赋值给指针 max 所指的变量,否则将 b 赋值给它
- *min = a < b? a : b; // 如果 a 小于 b,将 a 赋值给指针 min 所指的变量,否则将 b 赋值给它
- }
-
- // 函数:交换两个指针所指变量的值
- void swap(int *a, int *b)
- {
- int temp = *a; // 临时变量 temp 存储指针 a 所指变量的值
- *a = *b; // 将指针 b 所指变量的值赋给指针 a 所指的变量
- *b = temp; // 将临时变量 temp 的值赋给指针 b 所指的变量
- }
-
- // 主函数
- int main()
- {
- int a = 2; // 定义并初始化变量 a 为 2
- int b = 3; // 定义并初始化变量 b 为 3
-
- int max; // 定义变量用于存储最大值
- int min; // 定义变量用于存储最小值
-
- // ADD(&a,b); // 调用 ADD 函数,将 b 的值加到 a 上
- // printf("sum = %d\n",a); // 输出相加后的结果
-
- // maxandmin(a,b,&max,&min); // 调用 maxandmin 函数找出 a 和 b 的最大值和最小值
- // printf("max = %d, min = %d\n",max,min);
-
- printf("a = %d b = %d\n",a,b); // 输出原始的 a 和 b 的值
- swap(&a,&b); // 调用 swap 函数交换 a 和 b 的值
- printf("a = %d b = %d\n",a,b); // 输出交换后的 a 和 b 的值
-
- return 0;
- }

1、数组名代表数组首元素的地址,就是数组所在空间的首地址。例如:定义一个指向整型数组的指针变量可以写成 int *p = a; 或者 int *p = &a[0]; ,表示 p 指向了数组 a 。
2、数组名(数组首元素的地址)和 &a[0] 等价。
3、*p 等价于 a[0] 。
4、指针的运算:
&:取地址运算符。
*:解引用运算符。
p + 1:指针的算术运算,其偏移量取决于指针所指向的数据类型的大小。
指针的比较:
> >= < <= == !=
可以比较两个指针的大小或相等关系,但前提是这两个指针指向同一个数组或具有相同的基类型。
- #include <stdio.h>
-
- // 函数:打印数组元素
- void printfArray(int *begin, int *end)
- {
- // 只要起始指针不超过结束指针,就持续执行循环
- while (begin <= end)
- {
- // 打印起始指针所指向的元素,并将起始指针向后移动一位
- printf("%d ",*begin++);
- }
- // 换行,使输出更清晰
- printf("\n");
- }
-
- // 函数:找出数组中的最大值
- int maxArray(int *a, int len)
- {
- int i; // 定义循环变量
- // 初始化最大值为数组的第一个元素
- int max = *a;
-
- // 遍历数组的每一个元素
- for (i = 0; i < len; i++)
- {
- // 如果当前最大值小于数组中的某个元素
- if (max < *(a + i))
- {
- // 更新最大值为该元素
- max = *(a + i);
- }
- }
-
- // 返回最大值
- return max;
- }
-
- // 函数:反转数组元素的顺序
- void reversedOrder(int *begin, int *end)
- {
- int temp; // 定义临时变量用于交换元素
-
- // 只要起始指针小于结束指针,就持续执行循环
- while(begin < end)
- {
- // 交换起始指针和结束指针所指向的元素
- temp = *begin;
- *begin = *end;
- *end = temp;
- // 起始指针向前移动一位
- begin++;
- // 结束指针向后移动一位
- end--;
- }
- }
-
- // 函数:选择排序
- void choieSort(int *begin, int *end)
- {
- int *p = begin; // 定义指向起始位置的指针
- int *q = NULL; // 定义用于遍历的指针
-
- // 外层循环控制排序的轮数
- for (p = begin; p < end; p++)
- {
- // 内层循环在每一轮中找出最小元素
- for (q = p + 1; q <= end; q++)
- {
- // 如果当前元素大于后面的元素
- if (*p > *q)
- {
- // 交换两个元素
- int t = *p;
- *p = *q;
- *q = t;
- }
- }
- }
- }
-
- // 函数:冒泡排序
- void bubbleSort(int *begin, int *end)
- {
- int *p = begin; // 定义指向起始位置的指针
- int *q = NULL; // 定义用于遍历的指针
-
- // 外层循环控制排序的轮数
- for (p = end; p > begin; p--)
- {
- // 内层循环在每一轮中比较相邻元素
- for (q = begin; q < p; q++)
- {
- // 如果当前元素大于下一个元素
- if (*q > *(q + 1))
- {
- // 交换两个相邻元素
- int t = *q;
- *q = *(q + 1);
- *(q + 1) = t;
- }
- }
- }
- }
-
- // 函数:插入排序
- void insertSort(int *begin, int *end)
- {
- int *p = begin; // 定义指向起始位置的指针
- int *q = NULL; // 定义用于遍历的指针
-
- // 从第二个元素开始遍历
- for (p = begin + 1; p <= end; p++)
- {
- int t = *p; // 保存当前要插入的元素
- q = p; // 记录当前位置
-
- // 寻找插入位置
- while (q > begin && *(q - 1) > t)
- {
- // 将较大的元素向后移动
- *q = *(q - 1);
- q--; // 指针向前移动
- }
- // 插入元素
- *q = t;
- }
- }
-
- // 函数:折半查找
- int * binaryFind(int *begin, int *end, int n)
- {
- int *mid = NULL; // 定义指向中间位置的指针
- int *ret = NULL; // 定义用于存储查找结果的指针
-
- // 只要查找范围存在(起始指针小于等于结束指针)
- while (begin <= end)
- {
- // 计算中间位置
- mid = begin + (end - begin) / 2;
-
- // 如果要查找的值小于中间值
- if (n < *mid)
- {
- // 在左半部分继续查找
- end = mid - 1;
- }
- // 如果中间值小于要查找的值
- else if (*mid < n)
- {
- // 在右半部分继续查找
- begin = mid + 1;
- }
- // 如果找到匹配的值
- else
- {
- // 记录找到的位置
- ret = mid;
- break; // 退出循环
- }
- }
-
- // 返回查找结果,如果未找到则为 NULL
- return ret;
- }
-
- // 函数:折半查找(递归)
- int *binaryFindR(int *begin, int *end, int n)
- {
- int *mid = begin + (end - begin) / 2; // 计算中间位置
- int *ret = NULL; // 定义用于存储查找结果的指针
-
- // 如果起始指针大于结束指针,说明未找到
- if (begin > end)
- {
- return NULL;
- }
-
- // 如果要查找的值小于中间值
- if (n < *mid)
- {
- // 在左半部分递归查找
- end = mid - 1;
- ret = binaryFindR(begin, end, n);
- }
- // 如果中间值小于要查找的值
- else if (*mid < n)
- {
- // 在右半部分递归查找
- begin = mid + 1;
- ret = binaryFindR(begin, end, n);
- }
- // 如果找到匹配的值
- else if (*mid == n)
- {
- // 记录找到的位置
- ret = mid;
- }
-
- // 返回查找结果,如果未找到则为 NULL
- return ret;
- }
-
- // 函数:交换两个指针所指向的值
- void swap(int *a, int *b)
- {
- int t = *a; // 临时存储指针 a 所指向的值
- *a = *b; // 将指针 b 所指向的值赋给指针 a 所指向的位置
- *b = t; // 将临时存储的值赋给指针 b 所指向的位置
- }
-
- // 函数:快速排序
- void quickSort(int *begin, int *end)
- {
- // 记录起始位置和结束位置
- int *p = begin;
- int *q = end;
-
- // 选择起始位置的元素作为基准值
- int *k = begin;
-
- // 只要起始指针小于结束指针,就持续执行循环
- while (begin < end)
- {
- // 从右向左找小于基准值的元素
- while(begin < end && *end >= *k)
- {
- end--;
- }
-
- // 从左向右找大于基准值的元素
- while (begin < end && *begin <= *k)
- {
- begin++;
- }
-
- // 交换找到的两个元素
- swap(begin, end);
- }
-
- // 如果起始指针和结束指针相遇
- if (begin == end)
- {
- // 将基准值与相遇位置的元素交换
- swap(k, begin);
- }
-
- // 如果起始位置到结束位置减 1 的范围内还有元素,继续排序
- if (p < end - 1)
- {
- quickSort(p, end - 1);
- }
-
- // 如果起始位置加 1 到结束位置的范围内还有元素,继续排序
- if (begin + 1 < q)
- {
- quickSort(begin + 1, q);
- }
- }
-
- // 主函数
- int main()
- {
- int a[] = {10,2,8,5,4,6,7,3,9,1}; // 定义并初始化整数数组
- int len = sizeof(a)/sizeof(a[0]); // 计算数组的长度
-
- /*printf("max = %d\n",maxArray(a,len));
- printfArray(a,a+len-1); //可以改变打印的起始位置和结束位置
- reversedOrder(a,a+len-1);
- printfArray(a,a+len-1);*/
-
- //choieSort(a,a+len-1);
- //bubbleSort(a,a+len-1);
- printfArray(a,a+len-1);
- //insertSort(a,a+len-1);
- //printfArray(a,a+len-1);
-
- /*int n;
- scanf("%d",&n);
- //int *ret = binaryFind(a,a+len-1,n);
- int *ret = binaryFindR(a,a+len-1,n);
- if (ret==NULL)
- printf("no found\n");
- else
- printf("found\n");
- */
-
- quickSort(a,a+len-1); // 对数组进行快速排序
- printfArray(a,a+len-1); // 打印排序后的数组
-
- return 0;
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。