1.最普通的int型指针:
int a=5;
int*p= &a;
p=&a;
所以*p=*(&a)=a=5; *与&可以看作是一个逆运算
2.用一个初始化了的指针可以对新定义的指针进行初始化:
int a;
int*p=&a;
int*q=p;
3.指针为什么要区分类型:
int float char数据所占据的内存不同
如果定义一个int型的指针指向float数据,
double a=5.5;
int*p=&a;
此时*p只能取到前四个字节的数据,后四个字节的取不到
必须定义为double*p=&a,才可以取到八个字节
4.指针的运算
int a=4;
int *p=&a;
int b=*p++;
* 与++优先级相同
结合规则都是又结合
所以*p++等效与*(p++)
p++等效与p+sizeof(int)
p+5等效于p+5×sizeof(int)
指针不能与一般数据进行关系运算,但可以和null(0)进行关系运算判断是否是一个空指针
5.指针在函数的调用
例如:定义一个交换a,b数据的函数
void swap(int*p_one,int *p_two){
int *temp
temp=p_one;
p_one=p_two;
p_two=temp;
}
以上并不能进行数据交换,它只是交换了形参的地址,a,b的值并没有发生变换
正确的写法为
void swap(int*p_one,int *p_two){
int *temp;
*temp=*p_one;
*p_one=*p_two;
*p_two=*temp;
}
6.数组与指针
定义一个数组
int a[5]={1,2,3,4,5}
其实a就是一个指针,因为a可以代表数组的首地址,
(1)定义一个指向数组元素的指针变量
int a[5]={1,2,3,4,5};
int*p=a;
(2)利用指针访问数组的几种方式
int a[i]
1.*(a+i)
2.*(p+i)
3.p[i]
主意:a++是错误的,因为a是一个指针常量,不允许改变.
7.指针与二维数组
int a[3][3];
二维指针可以看作一个特殊的一维指针
a[3][3]={a[0],a[1],a[2]};所以a[3]可以看作一个b,也就是b[3]={a[0],a[1],a[2]};
因此a==&a[0] ==a[0] ==&a[0][0]==&a
a[0]==&a[0][0]
* ( a+1)==a[1]
a[0] +1==&a[0][1];
a[i][j]=*(*(a+i)+j);
int *p=a;//这句话使错误的,因为 p=a *p=*a=a[i];说明定义了一个指向一维数组的指针,定义方法应该为:
定义一个指向一维数组的指针
int(*p)[i]=a; \\ p相当于二维数组的行指针,整个式子相当于一个二维指针
访问方法:1.a[i][j]=*(*(p+i)+j);\\好处:可以用p++遍历数组,a是常量不能改变
2.p[i][j];
定义一个指针数组
int *p[i];
因此,括号一定不能少
字符串和指针
char str[]="abcd"
访问方法
1.char*p=str;
2.p="abcd"\\相当于直接把字符串的首地址赋值给了p;
char str[][10]={'"fjsklajfkla","fjdkslafjkl"};
char(*p)[10]=str;
printf("%s\n",str) ;
printf("%s\n",*str) ;
printf("%s\n",str[0]) ;
这两个打印出来是相等的,因为都指向了同一行都首地址.
char类型的指针数组
char*name[]={'"fjsklajfkla","fjdkslafjkl"};
name[]为一个指针数组,每一个元素都是一个指针,但是所指向的值为常量,值不能改变
野指针
int*p =(int*)malloc(100);
手动分配内存空间,当函数结束时,指针p释放,但是malloc没有释放,此时会造成内存泄露
因此手动分配内存时,必须
加上free(p);
指针函数
即为:返回值为指针的函数
定义方法
int *max(int a,int b){
return a>b?&a:&b\\返回的必须是指向int类型的一个地址
};
函数指针:指向函数的指针
int sum(int a,int b);
int (*p) (int,int)//可以不用写形参名
p=sum // sum代表了这个函数的首地址
拓展:指向指针函数的函数指针
int *max(int a,int b){
return a>b?(&a):(&b) ; }
int main(){
int *(*p)(int,int)=max;
int s=*p(5,3);
printf("%d",s);
}
结构体指针
1.指向结构体变量的指针
struct person s1;
struct person *p1;//该指针只能指向person类型的结构体
定义的同时进行初始化
struct person {}s1,*p;
2.结构体指针间接访问变量的值
1) struct person {
int lunzi;
int sudu;
}s1,*p;
p=&s1;
(*p).lunzi
2) struct person {
int lunzi;
int sudu;
}s1,*p;
p=&s1;
p->lunzi