1.初识指针
1.1了解指针之前,先明白地址是什么
地址:计算机运行时,数据会存放在内存中,内存会以字节为单位划分为多个存储空间,并且为每个字节默认设置一个对应的编号,这个编号就是地址。
指针变量: 本质是一个变量, 这个变量专门用来存放地址.
指针: 指针是一个类型,专门用来申请变量. (像int,char一样是个类型)
1.2.了解与指针相关的运算符
- & : 取地址运算符, 获取变量的地址.
- * : 取值运算符
-
指针的定义
格式: <存储类型> <指向的数据类型> *标识符;
例如:int *p; //** 定义一个指针p, 指针p指向一个int类型的变量
-
* 预算规则:
-
左值: *指针 .获取地址执行的空间, 然后将右值赋值给这个空间.
-
右值: *指针 获取这个地址里面的值.
-
-
左值与右值
-
左值: = 左边的值, 称之为左值
-
右值: = 右边的值, 称之为右值. 没有=, 默认为右值.
-
-
注意: 对于多字节变量, 取地址获取的是首地址, 标号最小的那个值。
-
int num = 10;
int sum = 10;
int* p = #
sum = sum + *p;//右值*p等于10;
printf("sum=%d\n", sum);
printf("num的地址为%x\n", p);//p是一个变量,保存num的地址。
*p = 66;//*p是左值;所以把66存放到他保存的num的地址中。
printf("num变为:%d\n", num);//变成了66
代码结果为:
2.指针与一维数组
2.1一维数组:
int a[3] = {11,22,33};
a数组占用的内存大小:sizeof(int)*3
a数组成员的类型:int
a对应的类型是:int *
a+1移动的字节数是:4字节,移动了int大小
a++表达式是错误的,数组名是常量不能自加
&a对应的类型是:int (*)[3]
&a+1移动的字节数是:3*sizeof(int)=12字节
&&a表达式是错误的,不能对常量取地址。
a[0]的类型是:int
a[0]+1是取出a[0]中的值加1,a[0]没有改变
a[0]++表达式是正确的,相当于让a[0]中的值加了1
&a[0]的类型是:int *
&&a[0]表达式是错误的,地址常量不能取地址
&a[0]+1代表的就是&a[1]
2.2一维数组与一级指针
int main()
{
int num = 10;
int* p_num = #
printf("%d\n", *p_num);//默认右值
int arr[3] = { 9,8,6 };
int(*p)[3] = &arr;
printf("%p\n", arr);
printf("%p\n",p);
printf("%p\n",*p);
//这三个值相等,但意义不同。
printf("%d\t%d\t%d\n", sizeof(arr), sizeof(p), sizeof(*p));
//arr大小为12,代表整个数组,值为数组首地址。
// p为8,类型为指针,代表数组存放的地址,值为数组首地址。
//*p为12,代表,p地址中存放的内容,也就是整个数组值为数组首地址。
printf("%d\t", **p);//输出9
//相当于*(*p),类型是int,是数组的第一个元素
printf("%d\n", **p + 1);//输出10,int类型相加是值相加
printf("%d\t%d\t%d\n", *(*p + 1),*(arr+1),arr[1]);//输出8.等价。
//类型为int *,相加移动4个字节。
printf("%d\n", *(p + 1));//p类型是int(*)[3],加1移动整个数组大小,12字节。
}
总结:
一级指针和一维数组的关系?
int a[3];int *p;
p = a
3.一级指针与二维数组
3.1二维数组
int a[4][3];
(int [3]) a[4];
a数组占用的字节数是:4*3*sizeof(int)
a的类型是:int(*)[3]
a+1移动的字节数是:3*sizeof(int)=12字节
&a的类型是:int (*)[4][3]
&a+1移动的字节数是:4*3*sizeof(int)
a[0]第0行的地址,它的类型是:int *
a[0]+1移动的字节数是:4字节
a[0][0]
的类型是int类型
a[0][0]+1
取出a[0][0]
中的值加1
&a[0][0]
的类型是:int *
&a[0]
:的类型是:int (*)[3]