------- ios培训、 android培训、java培训、期待与您交流! ----------
一.指针
1.内存中最小的单元是字节,每一个字节都有编号,这编号就是指针。
指针:内存地址
有了指针就有了打开这块内存的钥匙,就可以操作这一块内存
2.指针变量:存放内存地址的变量。
3.定义指针:指针所指向数据类型 *指针变量名称
代码演示:
#include <stdio.h> int main(int argc ,const char *argv[]{ int num = 10; int *p; p = # *p = 20; printf("num=%d\n",num); return 0; }
* 是一个类型说明符,说明定义的变量是指针变量
在不是定义变量的时候, * 是操作符,访问(读、写)指针所指向的那块存储空间。
* 和 & 是一对反操作符 ,*访问指针所指向的存储空间,&是取地址符
4.指针的初始化
注意:(1.)定义而没有初始化的指针,里面存放的是垃圾值,我们称为野指针
(2.)操作野指针会导致程序崩溃,访问你不该访问的存储空间,操作潜在逻辑错误
(3)不可以使用整型常量赋值给一个指针变量,因为内存是系统分配的,不是我们随便取的
4.1 先定义再进行初始化
代码演示:
int num =10;
//定义一个指针变量
int *p;
*p = &num // 这一步是错误的,p还没有初始化,不能够访问它所指向的存储空间
p = # // 这一步是正确的,对指针变量p进行了初始化
*p = 20 //访问其指向的存储空间,即变量num的存储空间
4.2定义同时初始化
代码演示:
int num2 = 20; // 定义一个变量
int *p = &num2; // 定义的同时进行初始化,现在指针变量p已经指向了num
*p2 = 40; // 访问num 所在的存储空间
二.练习
指针的使用场景:
在被调函数中,通过形参来改变主调函数的某个值
由于函数只能有一个返回值,指针可以让函数返回多个值
1.写一个函数交换两个变量的值
错误代码示范:
void swap1(int *num1,int *num2) { int *temp = num1; num1 =num2; num2 = temp; }
错误原因:这里仅仅是指针的指向进行交换,并没有改变它所指向存储空间的值
如果不使用指针操作符,那么你操作的都是指针变量本身,与它所指向的存储空间无关
正确代码示范:
void swap1(int *num1,int *num2) { int temp = *num1; *num1 =*num2; *num2 = temp; }
2.写一个函数,返回2个数的和、差
1 #include <stdio.h> 2 3 void sumAndMinus(int num1,int num2,int *sum,int *minus) 4 5 { 6 7 *sum = num1 + num2; 8 9 *minus = num1 - num2; 10 11 } 12 13 int main(int argc ,const char *argv[]{ 14 15 int a = 10; 16 17 int b = 20; 18 19 int sum,minus; 20 21 //调用函数 22 23 sumAndMinus(a,b,&sum,&minus); 24 25 printf("%d,%d\n",sum,minus); 26 27 return 0; 28 29 }
三.多级指针
四.指针为什么区分类型
所有的指针类型都是占用8个字节的存储空间
1.变量的地址是变量所占存储空间的首地址
2.指针变量仅仅可以存储一个地址编号,如果没有类型,指针就不知道要访问多少个字节的存储空间
3.指针区分类型是为了能正确访问它所指向的存储空间
4.如果通过一个char类型的指针操作一个int类型变量,如果变量值的二进制值超过一个字节,就会导致数据报错
5.如果通过一个int类型的指针操作一个char类型变量,那么就会修改不该修改的内存,造成程序逻辑错误
五.指针与数组
1.指针与一维数组
数组像一个指针:访问数组中的元素,使用数组与使用指向这个数组的指针是等价的
数组不是一个指针:
(1)sizeof(array)!=sizeof(pointer);当一个数组赋值给一个指针变量的时候,那么数组有些信息会丢失,比如数组长度,这种现象称为指针信息遗失
(2)指针的指向可以改变,数组的指向不可以改变array == &array
(3)自己的理解:
num[1] == p[1]
num+1 == p+1
nums[1]的本质是*(nums+1)
规律:指针+整数 ==指针中的值 + sizeof(所指向的数据类型)*整数
2.指针与二维数组
(1)指针数组:元素为指针的数组
格式: 指针类型 数组名称[指针元素个数] int *ps[5];
(2)数组指针:指向数组的指针
指向一维数组的指针 int (*ps)[元素个数];
指向一维数组的指针它是和二维数组相对应
(3)自己的理解
int nums[3][3] = {1,2,3,4,5,6,7,8,9};
pointer = nums;
pointer+1 // +一个其所指向的一维数组长度
nums + 1 // +一个它里面一维数组的长度
nums[1]+1 // +一个一维数组的元素长度
六.指针与函数
1.指针函数:返回值为指针的函数
局部变量的地址不可以作为函数返回值,因为局部变量在函数结束的时候会被系统回收
2.函数指针:指向函数的指针
(1)定义格式:
指针所指向的函数返回值类型 (*函数指针名称)(指针所指向的函数形参列表)
(2)定义步骤:
拷贝所要指向的函数
把函数名称用小括号括起来
在函数名称前面加一个*
函数名称换成指针名称
Ps:函数指针的指向是可以改变的,但必须指向同类型的函数(返回值类型与形参列表都相同)
代码演示:
1 #include <stdio.h> 2 3 int sum(int num1,int num2) 4 5 { 6 7 return num1+num2; 8 9 } 10 11 int minus(int num1,int num2) 12 13 { 14 15 return num1-num2; 16 17 } 18 19 int main(int argc ,const char *argv[]{ 20 21 //定义一个函数指针 22 23 int (*p)(int num1,int num2); 24 25 p = sum;// 函数指针p指向了函数sum 26 27 //int rs = p(10,20) 28 29 printf("rs=%d\n",rs); 30 31 p = minus;// 函数指针p指向了函数minus 32 33 rs = p(10,20); 34 35 printf("rs=%d\n",rs); 36 37 return 0; 38 39 }