指针
指针
#include<stdio.h>
int main()
{
//利用指针获取数据
int a = 10;
//定义一个指针变量指向变量a
int* p = &a;//这个*是一个指针标记和下方做区别
printf("%d\n", *p);
//*p中的*表示解地址
*p = 200;//利用指针修改数据
printf("%d\n", *p);
return 0;
}
- 指针变量名字是p
- 指针数据类型要和指向变量的类型保持一致
- 指针变量占用的大小,跟数据类型无关,跟编译器有关,32位的是4字节,64位是8字节
指针的作用
- 操作其他函数中的变量
- 函数返回多个值
- 函数的结果和计算状态分开
#include<stdio.h>
void swap(int* num1, int* num2);
int main()
{
//定义两个变量,交换变量中记录的值
int a = 10;
int b = 20;
int* p1 = &a;
int* p2 = &b;
printf("%d, %d\n", a, b);
swap(p1, p2);
printf("%d, %d\n", a, b);
return 0;
}
void swap(int* num1, int* num2)
{//如果用变量,只会传递a,b变量的值。
int temp = *num1;
*num1 = *num2;
*num2 = temp;
}
指针作用细节
函数中变量的生命周期跟函数相关,函数结束,变量也会消失,此时在其他函数中,就无法通过指针使用。如果不想函数中的变量被回收,可以在变量前面加static关键字变成静态指针,也叫全局指针。
#include<stdio.h>
int main()
{
int* p = method();
printf("time");
printf("%d\n", *p);//不能打印,method函数结束后,该函数里面所有的变量也会随之消失
return 0;
}
int* method()
{
int a = 10;//在前面加上static关键字就可以不被删除
return &a;
}
作用二:返回多个数据
#include<stdio.h>
void getmax(int arr[], int len, int* max, int* min);
int main()
{
//定义一个函数,求最大值和最小值
int arr[] = { 1, 2, 3 };
int len = sizeof(arr) / sizeof(int);
int max = arr[0];
int min = arr[0];
getmax(arr, len, &max, &min);//函数传递max和min的地址
printf("%d,%d", max, min);
return 0;
}
void getmax(int arr[], int len, int* max, int* min)
{
for (int i = 0; i < len; i++)
{
if (arr[i] > *max)
{
*max = arr[i];
}
}
for (int i = 0; i < len; i++)
{
if (arr[i] < *min)
{
*min = arr[i];
}
}
}
作用三:函数结果和计算状态分开
#include<stdio.h>
int getreminder(int a, int b, int* res);
int main()
{
//定义一个函数,求两个数的余数
int a = 10;
int b = 3;
int res = 0;//定义一个数用于接受余数
int flag = getreminder(a, b, &res);//传递参数只用传递res的地址
if (!flag)
{
printf("余数为:%d\n", res);
}
return 0;
}
int getreminder(int a, int b,int* res)//表示res是个指针变量
{
if (b == 0)
{
return 1;
}
*res = a % b;//解引用res。改变res地址的值
return 0;
}
野指针和空指针
#include<stdio.h>
int* method();
int main()
{
//野指针,指向空间未分配
int a = 10;
int* p = &a;
printf("%p\n", p);
printf("%d\n", *p);
int* p1 = p + 10;
printf("%p\n", p1);
printf("%d\n", *p1);
//悬浮指针,指针地址空间已经被释放
int* p2 = method();
printf("asdf\n");//拖时间,如果没有这句,函数定义的局部变量还没有被释放
printf("%p\n", p2);
printf("%d\n", *p2);
return 0;
}
int* method()
{
int num = 10;
int* p = #
return p;
}
结果:
0116F72C
10
0116F754
23165464
asdf
0116F624
10098975
二级指针和多级指针
#include<stdio.h>
int main()
{
int a = 10;
int b = 20;
int* p = &a;
//定义二级指针
int** pp = &p;
//作用一:利用二级指针修改一级指针里面记录的内存地址
printf("%p\n", p);
*pp = &b;
//作用二:利用二级指针获取到变量中记录的数据
printf("%p\n", &a);
printf("%p\n", &b);
printf("%p\n", p);
printf("%d\n", **pp);
return 0;
}
结果:
008FFD98
008FFD98
008FFD8C
008FFD8C
20
数组指针
#include<stdio.h>
int main()
{
int arr[] = { 10,20,30,29,32 };
int len = sizeof(arr) / sizeof(int);
//获取数组指针
// 实际上获取的数组首地址
int* p1 = arr;
int* p2 = &arr[0];
for (int i = 0; i < len; i++) {
printf("%d\n", *p1);
p1++;
//或者表达为一行printf("%d\n", *p1++);
}
return 0;
}
结果:
10
20
30
29
32
数组指针细节
arr参与计算的时候,会退化为第一个元素的指针
特殊情况,利用sizeof计算整个数组大小时候,不会退化,arr还是整体。
二维数组
两种定义方式
遍历
用索引遍历第一种二维数组
#include<stdio.h>
int main()
{
//定义二维数组
int arr[3][5] = {
{1,2,3,4,5},
{11,22,33,44,55},
{12,23,43,54,15},
};
//利用索引方式进行遍历
//arr[0]:表示二维数组中的第一个一维数组,{1,2,3,4,5}
//arr[1]:表示二维数组中的第二个一维数组,{11,22,33,44,55}
//arr[2]:表示二维数组中的第三个一维数组,{12,23,43,54,15}
for (int i = 0; i < 3; i++)
{
//依次表示二维数组中的索引
for (int j = 0; j < 5; j++)
{
//j:依次表示一位数组中的索引
//内循环:遍历每一个一维数组
printf("%d ", arr[i][j]);
}
//当内循环结束之后,表示一维数组遍历完成
printf("\n");
}
return 0;
}
遍历第二种索引
#include<stdio.h>
int main()
{
//第二种方法定义二维数组
int arr1[] = { 1,2,3 };
int arr2[] = { 2,12,13,14 };
int arr3[] = { 1,321,312,32,24,42 };
int* arr[3] = { arr1,arr2,arr3 };//存入的是三个一维数组的地址
//利用索引方式进行遍历
//再定义一个数组,存所有数组长度
int len1 = sizeof(arr1) / sizeof(int);
int len2 = sizeof(arr2) / sizeof(int);
int len3 = sizeof(arr3) / sizeof(int);
int lenArr[3] = { len1,len2,len3 };
for (int i = 0; i < 3; i++)
{
//依次表示二维数组中的索引
for (int j = 0; j < lenArr[i]; j++)
{
//j:依次表示一位数组中的索引
//内循环:遍历每一个一维数组
printf("%d ", arr[i][j]);
}
//当内循环结束之后,表示一维数组遍历完成
printf("\n");
}
return 0;
}
函数指针
#include<stdio.h>
void method1();
int method2(int a, int b);
int main()
{
//函数指针
//定义指针指向两个函数
void (*p1)() = method1;
int (*p2)(int, int) = method2;
//利用函数指针调用函数
p1();
int nu = p2(1, 2);
printf("%d\n", nu);
return 0;
}
void method1()
{
printf("method1\n");
}
int method2(int a, int b)
{
printf("method2\n");
int num = a + b;
return num;
}
结果
method1
method2
3