指针运算 和 函数指针
1. 二级指针和多级指针
二级指针:对地址再取地址
多级指针:三级和三级以上的指针。
#include <stdio.h>
void main() {
int num =12;
int* p= # // int*指针,&取地址
int** sp = &p; // 对一级指针取地址。
printf("p的值是:%p, sp的值是:%p", p, sp);
// sp的值是 0x0023FE34, 上面存的值是 p的地址。
// 0x0023FE34 就是p的地址,p上面存的值0023fe40(num的地址),num上存的值就是12.
// 通过二级指针,如何获取最终的值。**sp
printf("sp获取最终的值: %d", *(* sp) );
}
2. 数组和数组指针(重点)
如何获取数组的指针
for循环在c/c++ 中的正确写法. 否则部分ubuntu 可能不通过。
int i = 0;
for(; i<4; i++) {
// ...
}
void main() {
int arr[] = {1,2,3,4}; // 定义数组
// for(int i=0; i<4; i++) { // 遍历数组
// printf("%d value: %d", i, arr[i]);
// }
// printf("arr = %p \n", arr); // arr = &arr, arr地址的值 = &(arr[0])- 首地址
// printf("arr& = %p \n", &arr);
// printf("arr[0]& = %p \n", &(arr[0]));
// arr[0], 就是首地址
// 如何获取数组的指针? 数组指针,可以直接用arr。
int* arr_p = arr; // 相当于 int* arr_p = &arr; 数组指针指向的是数组的首地址。
printf("%d", *arr_p); // 打印1
// 对指针++
arr_p ++; // 指向下一个元素.
printf("%d", *arr_p); // 打印2
getchar();
}
数组指针int,等于数组的首地址。 int arr_p = arr; // 相当于 int* arr_p = &arr;
3. 指针循环遍历 和 循环赋值
void main() {
int arr[] = {1,2,3,4};
int* arr_p = arr;
for(int i=0; i<4; i++) {
printf("%d\n", *(arr_p +i)); // 通过指针遍历
}
}
void main() {
int arr[4] ;
int* arr_p = arr;
for(int i=0; i<4; i++) {
*(arr_p +i) = i; // 指针循环赋值:0,1,2,3。 数组数据填充
}
for(int i=0; i<4; i++) {
printf("%d\n", *(arr_p +i));
}
}
4. 函数指针 与数组的几种写法
另一种方式,直接操作arr
int arr[] = {1,2,3,4};
int* arr_p = arr;
for(int i=0; i<4; i++) {
printf("%d\n", *(arr +i)); // 1.通过指针遍历
printf("%d\n", arr_p[i]); // 2.拿到数组里面的值,相当于 *(arr_p +i)
}
指针为什么有类型?
int, double, char*
指针就是一块地址,而且它的值都差不多。
- 取值得时候,要知道怎么取,取多少个字节。按几个字节取(根据类型)。
- 指针的偏移,要知道类型(偏移多少个字节)
void main() {
int num = 12;
double* num_p = #
}
5.函数指针(回调)
NDK_Day3: 监听视频压缩的进度,传入本地的call_back() 方法,传方法指针 void(call_back)(int,int)
就能监听到回调,
void add(int num1, int num2) {
printf("num1+num2 = %d\n", num1+num2);
}
void min(int num1, int num2){
printf("num1-num2 = %d\n", num1-num2);
}
// 方法指针,传入函数method
void operate(void(*method)(int, int), int num1, int num2) {
method(num1, num2);
}
void main() {
// add(1, 4); // 另一个文件不能直接调用方法,要吧方法指针传给另一个文件。
// 方法指针的定义: 方法的返回值(*方法的名称)(方法的参数)
// void(add_p)(int, int) = add; //?
operate(add, 1, 2);
operate(min, 10, 2);
}
// 监听压缩回调
void call_back(int current, int total) {
printf("压缩进度:%d/%d\n", current, total);
}
// 压缩代码,在额外的文件中(不在同一个地方),传入方法的*可以去掉。
void compress(char* file_name, void(*callback)(int,int) ) {
callback(12, 20);
}
void main() {
// compress("1.png", call_back); // ①.传入回调方法
void(*call)(int, int) = NULL; // 声明一个函数指针
call = call_back; // 给函数指针赋值
call(1, 10); // ②.通过函数指针,间接调用方法。
compress("1.png", call); // ③.也可调用
}
java有接口回调,c有方法回调. 应用:视频压缩,指针回调。
#include <stdlib.h>
void print(char* message) {
printf("打印内容11:%s", message);
}
// 把函数指针作为参数传递。
void method( void(*print_s)(char*)){
print_s("把函数指针作为参数传递。");
}
void main() {
// 方法指针定义 用一个指针接收print方法
// 函数指针 语法:方法的返回值(*方法名称)(参数列表) ,*可以省略。
void(*print_s)(char*) = print; // 方法指针接收方法,print就是个方法指针。
// print 与 &print 的值,是相同的。
method(print_s);
}
面试题:c/c++ 判断是否是平衡二叉树。翻转单链表。
网友评论