一级指针:
难点1,指针是怎样保存一个地址
例如: char str1[]="hello world"(这里虽然定义的是数组,但其实在初始化时隐式退化成指针,保存的是首字符的地址'h')
char *str2="hello world"(这里表示str2指向一个常量字符串),如果这时还有一个char str3[]="hello world",和char* str4="hello world",那么str1==str3? str2==str4?
str1和str3存的是一个地址,两个字符数组的内存地址不一样,故str1!= str2
而str2和str3指向同一个常量字符串的地址,所以str2 == str4
难点2,指针作为参数要注意的点
指针作为函数的形参时,改变形参指针q的指向并不会改变实参指针p的指向(即输出的值不变),如果要改变输出的值,就需要对指针指向的内容进行改变(解引用形参指针q)
#include<stdio.h>
//错误的例子,这样是无法改变输出结果的
void test(int* q){
q = 50;
}
int main(){
int a = 10;
int* p = &a;
test(p);
printf("%d", *p);
return 0;
}
二级指针
二级指针保存的是地址的地址,也就是一级指针的地址,二级指针**pp和一级指针*p和一级指针指向的常量a之间的关系就是,常量a改变->一级指针p改变->二级指针pp改变,对二级指针进行一级解引用*pp,其实得到的就是一级指针p的地址,改变*pp的值就是改变p的值,对二级指针进行二级解引用**pp得到的就是a的地址,改变**pp的值就是改变a的值
二级指针的用法
#include<stdio.h>
void test(int** ptr){
printf("%d\n", **ptr);
}
int main(){
int n = 666;
int* p = &n;
int** pp = &p;
test(pp);
test(&p);
return 0;
}
指针数组和数组指针
指针数组int* p1[10]实质上是一个数组,数组指针int (*p2)[10]实质上是一个指针,
对于数组指针int(*p)[10] 和指针数组int* arr[10] ,p+1 和 arr+1的意义完全不一样,数组指针的p+1表示跳到下一个数组(对于这个数组而言就是跳过了十个元素,用地址来说就是跳过了10*4个字节),arr+1表示跳到下一个指针
指针数组的用法:int arr[10]={1,2,3,4,5,6,7,8,9,0} int (*p)[10]=&arr 每个p指针指向一个数组的地址,p+1指向下一个数组的地址
数组指针的用法: int arr[10]={1,2,3,4,5,6,7,8,9,0} int *p[10]=&arr 每个p指针指向一个元素的地址,p+1指向下一个元素的地址