// // main.c // 指针基本概念 #include <stdio.h> // 基本数据类型作为函数的参数是值传递, 在函数中修改形参的值不会影响到外面实参的值 void change(int value) // int value = 10; { value = 55; printf("哥被执行了 "); } // 数组作为函数的参数是地址传递, 如果是地址传递在函数中修改形参的值会影响到外面实参的值 void change2(int values[]) { values[1] = 88; printf("哥被执行了 "); } // 指针就是专门用于保存地址的 void change3(int *p) // 用什么接收地址? 指针 = 0ffc13 int *p = # { *p = 55; printf("哥被执行了 "); } int main(int argc, const char * argv[]) { // 需求: 定义一个函数, 在函数中修改传入的实参的值 int num = 10; printf("修改前:num = %i ", num);//10 change(num); printf("修改后:num = %i ", num);//10 int nums[] = {1, 3}; printf("修改前:nums[1] = %i ", nums[1]);//3 // nums == &nums == &nums[0] change2(nums); printf("修改前:nums[1] = %i ", nums[1]);//88 int num = 10; // *p == num printf("修改前:num = %i ", num);//10 change3(&num); printf("修改后:num = %i ", num);//55 /* 如何定义指针变量 普通变量: 数据类型 变量名称; 指针变量: 数据类型 * 变量名称; 数据类型 : 说明将来指针变量能够保存什么类型的变量的地址 注意: 指针变量是什么类型, 那么将来就只能保存什么类型变量的地址, 例如: 指针变量是int类型, 那么将来就只能保存int类型变量的地址 * : 没有任何特殊含义, 仅仅是为了标示这是一个指针变量 变量名称 : 用于区分不同的变量 */ int num; // 普通变量 num = 10; int *p; // 指针 , 在64位编译器下占用8个字节 // 千万注意: 指针变量只能存储地址 p = # // 将num的地址存储到p这个指针中 // p == &num printf("num = %p ", &num);//num的地址,0xff90c printf("p = %p ", p);//p里面的值,0xff90c // 指针变量前的*号代表访问指针变量指向的那一块存储空间 // *p == num *p = 55; printf("num = %i ", *p); return 0; }
// // main.c // 指针练习1 // // Created by xiaomage on 15/6/12. // Copyright (c) 2015年 xiaomage. All rights reserved. // #include <stdio.h> void swap(int *v1, int *v2) // int *v1 = &a, int *v2 = &b; v1 = 0ffc13 v2 = 0ffc9 // *v1 == a *v2 == b { int temp = *v1; // int temp = 0ffc13 *v1 = *v2; *v2 = temp; } int main(int argc, const char * argv[]) { // 定义一个函数交换两个变量的值 int a = 10; // 0ffc13 int b = 5; // offc9 printf("交换前:a = %i, b = %i ", a, b); // int temp = a; // a = b; // b = temp; swap(&a, &b); printf("交换后:a = %i, b = %i ", a, b); return 0; }
// // main.c // 指针练习2 #include <stdio.h> //int demo(int v1, int v2, int v3); int demo(int v1, int v2, int v3, int *p1, int *p2); int main(int argc, const char * argv[]) { // 要求定义一个函数, 传递三个值, 返回这三个值得和,差,平局值 int a = 10; int b = 20; int c = 30; //int res = demo(a , b , c); printf("res = %i ", res); // 定义三个变量用于保存计算结果 int res1 = 0; // 和 int res2 = 0; // 差 int res3 = 0; // 平局值 // *p1 == res1 *p2 == res2 // 我们想要的就是调用完函数之后, 和差平均值对应的变量都被"修改"为对应的值 int res3 = demo(a, b, c, &res1, &res2); printf("和 = %i, 差 = %i, 平均值 = %i ", res1, res2, res3); return 0; } int demo(int v1, int v2, int v3, int *p1, int *p2) { int sum = v1 + v2 + v3; *p1 = sum; int m = v1 - v2 - v3; *p2 = m; int average = sum / 3; return average; // 因为返回的是一个逗号表达式, 而逗号表达式的值是最后一个表达式的值, 所有返回的是average // return sum, m, average; // return 连个作用 1.返回值给调用者 2.结束函数 // 注意点: return后面不可以写任何语句, 因为执行不到 return sum; printf("-------------- "); return m; return average; }
// // main.c // 指针的注意点 #include <stdio.h> int main(int argc, const char * argv[]) { // 1.指针只能保存地址 int *p = 200; printf("%i ", *p); // 2.同一个变量可以有多个指针指向它 int num = 10; int *p = # // *p == num // num = 55; *p = 55; int *p1 = p; *p1 = 100; int *p2 = # printf("%i ", *p);//100 // 3.指针的指向可以修改 int a = 10; int b = 5; int *p = &a; *p = 88; p = &b; *p = 44; printf("%i ", a);//88 printf("%i ", b);//44 // 4.不要访问野指针 // 没有赋值的指针, 我们称之为野指针 int *p; int *p = NULL; // 0,不赋值就赋初值为null, printf("%i ", *p); // 5.指针类型是什么类型, 就只能指向什么类型的数据 int num = 10; char charValue = 'l'; double doubleValue = 9.9; // int *p = # // int *p = &charValue; // int *p = &doubleValue; double *p = &doubleValue; printf("%lf ", *p); return 0; }
// // main.c // 多级指针 // // Created by xiaomage on 15/6/12. // Copyright (c) 2015年 xiaomage. All rights reserved. // #include <stdio.h> int main(int argc, const char * argv[]) { char charValue = 'l'; // 1.拷贝需要指向的变量的数据类型和变量名称 // 2.在数据类型和变量名称之间加上一颗星 // 3.修改变量名称 char *charValueP; charValueP = &charValue; // 1.拷贝需要指向的变量的数据类型和变量名称 // 2.在数据类型和变量名称之间加上一颗星 // 3.修改变量名称 char **charValuePP; // 不管有几颗*只要是指针变量就占用8个字节 printf("size = %lu ", sizeof(charValuePP)); charValuePP = &charValueP; charValue = 'j'; *charValueP == charValue *charValueP = 'j'; &charValue == charValueP printf("&charValue = %p ", &charValue); printf("charValueP = %p ", charValueP); &charValueP == charValuePP printf("&charValueP = %p ", &charValueP); printf("charValuePP = %p ", charValuePP); // *charValuePP == 0ffc14 == charValueP // *pp == p // **charValuePP == *(*charValuePP) == *charValueP == 0ffc14 == l **charValuePP = 'n'; printf("%c ", **charValuePP); char c = 'a'; char *cp; cp = &c; char **cpp; cpp = &cp; char ***cppp; cppp = &cpp; printf("cppp = %c ", ***cppp); /* *cp == c; *cpp == cp; **cpp == *(*cpp) == *cp == c 多级指针的操作, 最简单的方式, 就是通过几颗星来存储, 就通过几颗星来访问 还有一种方式就是画图, 看图片中有几个箭头, 有几个简单就用几颗星来访问 */ printf("c = %c ", c); printf("*cp = %c ", *cp); printf("&c = %p ", &c); printf("cp = %p ", cp); printf("*cpp = %p ", *cpp); printf("**cpp = %c ", **cpp); return 0; }
// // main.c // 指针为什么要分类型 // // Created by xiaomage on 15/6/12. // Copyright (c) 2015年 xiaomage. All rights reserved. // #include <stdio.h> int main(int argc, const char * argv[]) { char *cp; int *ip; double *dp; double **dpp; // mac系统中的指针无论是什么类型, 几级真正都占用8个字节 // 由于Mac是64位了所以是8个字节,32位就是4个字节了, 32 = 4 * 8;(4个字节*每个字节占8位) 64 = 8 * 8;(8个字节*每个字节占8位) printf("cp = %lu, ip = %lu, dp = %lu, dpp = %lu ", sizeof(cp), sizeof(ip), sizeof(dp), sizeof(dpp));//8,8,8,8 // 指针为什么要分类型? // 因为当我们利用指针去取值的时候(指针只是首地址,不知道数据类型就不知道从首地址取多长), 系统就会自动根据指针的类型来确定应该取对少个字节中的值 int intValue = 1230; // char charValue = '1'; /* 00110001 11001110 00000100 00000000 00000000 00000100 11001110 00110001 */ int *charValueP; charValueP = &charValue; printf("%i ", *charValueP); printf("%i ", 0b00000000000001001100111000110001); /* 11001110 */ char *p = &intValue; printf("%i ", *p); return 0; }