- 指针和指针变量(结合语境判断)
指针就是地址,地址就是指针
指针变量:就是变量,保存地址的变量
指针的定义:type(数据类型)+*
不知道指针指向哪里时可以置为NULL,没有指向固定位置的指针为野指针
指针的大小在32位平台下是4字节,在64位平台下是8字节
#include<stdio.h>
int main()
{
int a=10;
int *p;//定义整型指针变量
p=&a;
printf("%d\n",p);
return 0;
}
- 指针+、-整数
对指针加减1是加减上其所指向类型的大小(指针指向的都是首地址,所以加减一是加减类型所占字节数)
指针的类型决定了指针向前或向后走一步有多大(距离)
#include <stdio.h>
int main()
{
int n = 10;
char* pc = (char *)&n;
int* p = &n;
printf("%p\n", &n);
printf("%p\n", pc);
printf("%p\n", pc+1);//char类型为1字节,指针加1就是加上其所指向类型的大小(也就是类型所占字节数)
printf("%p\n", p);
printf("%p\n", p+1);//int类型为4字节
system("pause");
return 0;
}
- 指针的解引用(*)
对指针的解引用代表指针所指向的目标
指针的类型决定了对指针解引用时能有多大的权限(能操作几个字节)
#include<stdio.h>
int main()
{int n=0x11223344;//这里还存在大小端机器的问题,一般都是小端:低位存低地址
char *p=(char *)&n;
int *p1=&n;
*p=0;
printf("p->n:%d\n",n);//char 型只占一字节,而n为int型四字节,只能改变一个字节
*p1=0;
printf("p1->n:%d\n",n);
return 0;
}
- 指针运算
1.指针+-整数
注意:结引用和++的优先级
#include <stdio.h>
int main()
{
int arr[] = { 1, 2, 3, 4, 5 };
int *p = &arr;
for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
{
printf("%d\n", *p++); //*和++同一级,此时从右往左运算,++>* 也就是先++再结引用
}
system("pause");
return 0;
}
2.指针减(-)指针
代表两个指针之间所经历的元素个数(元素由指针类型决定)
//例题1:
#include<stdio.h>
int my_strlen(char *_str)
{char *end=_str;
while(*end)
{end++;
}
return end-_str;
}
int main()
{char *str="hello bit";
int len=my_strlen(str);
printf("%d\n",len);
return 0;
}
//例题2
#include<stdio.h>
int main()
{int a[]={1,2,3,4,5};
int *p=a;
int *q=&a[4];
printf("%d\n",q-p);//4
printf("%d\n",(double *)q-(double *)p);//2
return 0;
}
- 指针和数组
1.数组名:(1)在sizeof中使用数组名,此时数组名代表整个数组
(2)取地址时数组名代表数组的地址 &a
(3)除以上两种情况外,所有的数组名都表示数组首元素的地址
#include<stdio.h>
int main()
{int a[]={1,2,3,4,5,6,7,8,9,0};
int *p=a;
int size=sizeof(a)/sizeof(a[0]);
int i=0;
for(;i<size;i++)
{printf("a[%d]=%p <----> p+%d=%p\n",i,&a[i],i,p+i);//指针+1是加减上其所指向类型的大小,指针的类型决定了指针向前或向后走一步有多大的距离
}
return 0;
}
#include<stdio.h>
int main()
{int a[]={1,2,3,4,5,6,7,8,9,0};
int *P=a;
int sz=sizeof(a)/sizeof(a[0]);
int i=0;
for(;i<sz;i++)
{printf("%d ",*(p+i));//p[i]
}
printf("%p\n",a);//首元素地址
printf("%p\n",&a[0]);//首元素地址
printf("%p\n",&a);//整个数组的地址
printf("%p\n",a+1);//下一个元素的地址
printf("%p\n",&a[0]+1);//同上,&a[0]相当于a
printf("%p\n",&a+1);//指向下一个数组
}
- 二级指针
二级指针-->存放一级指针的地址 (type**)(变量名)
#include<stdio.h>
int main()
{int a=10;
int *p=&a;
int **pp=&p;
pp=100;
*pp=100;// pp->p->p=100
**pp=100;//pp—>p->a->a=100
printf("%d\n",pp);
printf("%d\n",*pp);
printf("%d\n",**pp);
printf("%d\n",p);
printf("%d\n",a);
system("pause");
return 0;
}
#include <stdio.h>
int main()
{
double a = 10.0;
double *pa = &a;
double **ppa = &pa;
printf("%p\n", &a);
printf("%p\n", pa);
printf("%p\n", ppa);
printf("%p\n", &a + 1);//&a就是a的地址 而地址就是指针(+1其实是+8) double所占字节数为8
printf("%p\n", pa + 1);//+8 指针加一就是加上其类型的大小
printf("%p\n", ppa + 1);//+4
system("pause");
return 0;
}
- 指针数组
指针数组是数组,是存放指针的数组
(数组还是指针的评判标准是看数组名左右两端的操作符的优先级谁高;读的时候从优先级低的开始)
eg:
int *a[10] 指针数组
int (*a)[10]数组指针
int (*a[5])[10] 数组指针的数组
int ( *(*a)[5])[10] 数组指针的数组指针