C语言学习之指针类型_空指针_二级指针_指针运算_指针与数组实例讲解
程序员文章站
2022-07-05 22:47:34
c语言学习之指针类型_空指针_二级指针_指针运算_指针与数组实例讲解
#include
#include
#include
#include
#include
//1....
c语言学习之指针类型_空指针_二级指针_指针运算_指针与数组实例讲解
#include #include #include #include #include
//1.指针为什么要有类型? //指针有类型,地址没有类型 //地址只是开始的位置,类型读取到什么位置结束。 //指针是要有类型的,这样指针在移动时可以根据类型的大小来移动。如:int(4),p++是向下移动4个字节 /*void main(){ //int 4个字节 int i = 89; //int 类型的指针,这是p只能一次读取4个字节 int* p = &i; //double 8个字节 double d = 78.9; //这时将p的值修改为了double类型的地址 *p = d; //由于指针p是int类型,只能读取4个字节,所以读取d位置的4个字节78 printf("value: %d", *p); getchar(); }*/
//2. null指针 /*void main(){ //如 地址0x8ffe8c 值(9) int i = 9; printf("i指针的地址为:%#x \n", &i); // 地址0x6ffca8 值(0) int* p = null; printf("null指针的地址为:%#x \n", &p); //对p指针,地址的值重新赋值 //地址 00x6ffca8 值(0x8ffe8c) p = &i; //获取指针值的地址的值, printf("p指针的值为:%d \n", *p); getchar(); }*/
//多级指针,(二级指针),一般不会超过二级指针 /* 数据类型,int char float double 一级指针 int* char* 二级指针 int** char** 数据类型: 如 int a=9; 开辟了一块名为 0xfff000 的地址 值为9表示0xfff000(9) 一级指针,可以看成存放地址的数据类型 如 int* p=&a; 开辟了一块名为 0xfff111 的地址 值为0xfff000表示为 0xfff111(0xfff000) 二级指针,可以看成存放指针的数据类型 如 int** ff=&p; 开辟了一块名为 0xfff222 的地址值为0xfff111 表示为 0xfff222(0xfff111) 对于数据类型 a=9 &a=0xfff000 *&a=9 对于一级指针 p=0xfff000&p=0xfff111 *p=9 对于二级指针 ff=0xfff111 &ff=0xfff222 *ff=0xfff000 **ff=9 */ //指针保存的是变量的地址,保存的这个变量还可以是一个指针变量 /*void main(){ int a = 9; int* p = &a; int** ff = &p; printf("a的值:%da的地址:%#x\n", a, &a); printf("p的值:%#xp的地址:%#x 指向地址的值%d\n", p, &p,*p); printf("ff的值:%#xff的地址:%#x 指向地址的值%d\n", ff, &ff, **ff); getchar(); }*/
//指针的运算 //指针的运算一般在数组的遍历时才有意义,基于数组在内存中线性排列方式。 /*void main(){ //数组在内存中线性排列,中间间隔sizeof个数据类型 int ids[] = { 22, 33, 44, 55, 66 }; //都是表示数组的首地址 printf("ids的首地址:%#x\n", ids); printf("ids的首地址:%#x\n", &ids); printf("ids的首地址:%#x\n", &ids[0]); //将指针指向数组的首地址 int* p = ids; printf("数组的第一个值为:%d\n", *p); //p代表指针p的值地址,p++代表ids首地址向下移动sizeof(int)个字节, p++; printf("数组的第二个值为:%d\n", *p); getchar(); }*/
//通过指针给数组赋值 /*void main(){ int uids[5]; //高级写法 //int i = 0; //for (; i < 5; i++){ // uids[i] = i; //} //早些版本的写法 int* p = uids; //printf("%#x\n", p); for (int i = 0; i < 5; i++) { // *p = i; //p++; p[i]=i; } //打印数组 int* f = uids; for (int i = 0; i < 5; i++) { printf("value:%d\n", *f); f++; } getchar(); }*/
//函数指针 //由三部分组成: 函数返回值类型,函数指针的名称,函数的参数列表 //void(*fun)(char* msg, char* title) = msg; //这样就能通过fun指针来代替msg /*void msg(char* msg,char* title){ //弹窗 messagebox(0, msg, title, 0); }*/ /*void main(){ //两种方式都是获取函数地址,输出结果一致 printf("函数地址:%#x \n", msg); printf("函数地址:%#x \n", &msg); //直接调用方法 msg("消息", "标题"); //使用函数指针 //由三部分组成: 函数返回值类型,函数指针的名称,函数的参数列表 void(*fun)(char* msg, char* title) = msg; fun("函数指针的消息", "函数指针的标题"); getchar(); }*/
//函数指针的运用 //非常重要:可以将函数指针放到方法中,这样就能传递一个方法,和代理模式很相似。 /*int add(int a, int b){ return a + b; } int reduc(int a, int b){ return a - b; } //第一个参数就是函数指针等同于int(*fun)(int a, int b)=add //这里可以传入这种相似的函数 void operation(int(*fun)(int a, int b), int m, int n){ printf("开始运算前\n"); int result=fun(m, n); printf("执行结果:%d\n", result); } void main(){ //int(*func)(int a, int b) = add; //加法 operation(add, 10, 20); //减法 operation(reduc, 50, 10); getchar(); }*/
//案例:用随机数生成一个数组,写一个函数查找最小的值, //并返回最小数的地址,在主函数中打印出来 int* getminpointer(int ids[], int len){ int i = 0; int* p = &ids[0]; for (; i < len; i++){ if (ids[i] < *p){ p = &ids[i]; } } return p; } void main(){ int ids[10]; int i = 0; //初始化随机数发生器,设置种子,种子不一样,随机数才不一样 //当前时间作为种子 有符号 int -xx - > +xx srand((unsigned)time(null)); for (; i < 10; i++){ //100范围内 ids[i] = rand() % 100; printf("%d\n", ids[i]); } int* p = getminpointer(ids, sizeof(ids) / sizeof(int)); printf("%#x,%d\n", p, *p); getchar(); }