指针
计算机中所有的东西都需要有自己的存储空间,比如你int a=10;printf a的数值呈现出10的步骤是:先去访问存储着a的空间,再将空间中储存的数值10给你呈现出来。每一个空间都有它对应的编号,也可以说是地址,指针就是存储地址的空间的变量

*解引用的作用,指向指针p存储的内容(地址)对应的内容
指针基本法
1.指针的定义 type *name;可以char *p;也可以 int *p;全看你想要什么类型
然后我们 int *p=&a;这里用到了取地址符&,因为p储存的是a的地址嘛;我认为要 int (*p)的原因,是p存储a的地址,*p就相当于把他转化成了整型;或者说p是指针,不是整型,而*p是p指向的内容,这个内容是整型(10)(下面是64进制条件下)
or这么说,最开始定义是 int *p;p=&a;最后简化成了int *p=&a;(我觉得最开始的那个比较好理解,毕竟p存储的就是a的地址,在*的作用下才指向10,变成属于整型的变量)

2.因为指针存储的是地址,所以你改变指针就可以改变变量a的值(他直接改变的就是存储a的空间里的值)有一点绕了,就想象对于0x2246这个盒子,p可以随便把盒子里面的东西展现出来或者替换内容。然后这里也可以看到a和p的地址是不一样的

objectivec
#include <stdio.h>
#include <stdlib.h>
int main()
{
//point的大小
int a=10;
int *p=&a;
printf("%d\n",sizeof(a));
printf("%d\n",sizeof(*p));
printf("%d\n",sizeof(p));
//指针的使用
printf("%p\n",&a);
printf("%p\n",p);
printf("%p\n",&p);
printf("%d\n",a);
printf("%d\n",*p);
*p=30;
printf("%d\n",a);
return 0;
}
指针与函数
在前面function函数这一章节中,我们提到了传值和传地址。传值的时候形参改变不会对实参发生影响,但是传地址的时候形参改变实参也跟着改变了。这一点和上面说的也是一样的,就是直接把他那个盒子里面的东西改变掉
objectivec
#include <stdio.h>
#include <stdlib.h>
int function1(int a){
return a*a*a;}
void function2(int a){
a=a*a*a;
}
void function3(int *p){
*p=*p**p**p;}
int main()
{
int a=10;
int *p=&a;
printf("%d\n",function1(a));
function2(a);
printf("%d\n",a);
function3(&a);
printf("%d\n",a);
return 0;
}
可以通过function23来看区别,地址访问就可以改变实参了(function3输入的时候可以是 &a也可以是p哦)
下面这个代码,首先是函数中 i=*a而不是int *i=*a; *a已经是一个整型了,可以直接规定,就像int a=10一样,*a就相当于10了
objectivec
void swap(int *a,int *b){
int i=*a;
*a=*b;
*b=i;}
int main()
{
int a=5,b=10;
printf("a=%d b=%d",a,b);
swap(&a,&b);
printf("a=%d b=%d",a,b);
}
指针与数组
1.访问数组
格式 int a[];int*p=a;(这个时候p存储的是数组a第一个变量的地址 ==&a[0]这样子)他可以用来遍历数组,可以改变数组的某些变量等等
数组就是一个地址(存储了很多变量的空间集合),所以规定的时候出现的是int *p=a; 而不是&a。数组指针指向的都是数组的开头
objectivec
#include <stdio.h>
#include <stdlib.h>
int main ()
{
int a[5]={0,1,2,3,4};
int *p=a;
//遍历数组
for(int i=0;i<5;i++){
printf("%d\n",*p);
p++;}
for(int i=0;i<5;i++){
printf("a[%d]=%d\n",i,a[i]);
}
}
在改变数组某些元素值的时候,我尝试用p++来改变a[1]的值,但是后面遍历的时候a[0]="a[1]"并且a[0]没有了。

可以看到,在第一次遍历的时候,就是*p=a[0],之后p++就进入下一个单元;第二次遍历没成功是因为第一次的时候p已经到末尾了,你需要重置回到开头再进行操作
objectivec
#include <stdio.h>
#include <stdlib.h>
int main ()
{
int a[5]={0,1,2,3,4};
int *p=a;
for(int i=0;i<5;i++){
printf("%d\n",*p);
p++;
printf("\n");}
//修改数值
p=a;
*p=10;
p++;
*p=20;
p=a;
for(int i=0;i<5;i++){
printf("%d",*p);
p++;
printf("\n");
}
}
输出的时候可以用*p也可以用a[] 比如输出的时候 *(p+1)=a[1]
2.字符指针
(这个是我觉得这一part最复杂最难懂的)
char *p[3]={"hello","ok","name"};

在这里我就不懂为什么char单字符却可以规定出字符串,对于字符指针,他们指向的是数组各个元素的首字母,如果用%s就会从第一个开始读取直到\0,但如果是%c就只输出首字符
objectivec
int main()
{
char p[4]={'a','b','c','d'};
char *q[4]={"hello","ok","name","free"};
for(int i=0;i<4;i++){
printf("%c ",p[i]);
}
printf("\n");
for(int i=0;i<4;i++){
printf("%c ",*q[i]);
}
printf("\n");
for(int i=0;i<4;i++){
printf("%s ",q[i]);
}
}
char是规定单字符,字符串是"字符+\0"的组合形式
查了一下网上说"char*是通过识别首字母和\0构成字符串的"所以对于char *p就可以输出字符串