#include<stdio.h>
/**
* C语言指针基础
* @param a
* @param b
*/
void swap(int* a,int* b){
int tmp = *a;
*a = *b;
*b = tmp;
}
int main(){
//int* 就是一个指针变量
int* e = NULL;//此时,e是一个指针变量,必须给e赋初值为NULL,让它变成空指针
int a = 10;
//指针类型需要与变量的类型相同,且后面需要添加一个*符号(注意这里不是乘法运算)表示是对于类型的指针
int* p = &a; //这里的&并不是进行按位与运算,而是取地址操作,也就是拿到变量a的地址
printf("a在内存中的地址:%p\n",p); //地址使用%p表示
//以上通过取地址操作&,将变量a的地址保存到了一个地址变量p中
//拿到指针后,我们可以很轻松地获取指针所指地址上的值
printf("内存p上存储的值为:%d\n",*p); //我们可以在指针变量前添加一个*号(间接运算符,也可以叫做解引用运算符)来获取对应地址存储的值
//同样的,我们也可以去修改对应地址存放的值
*p = 20;
printf("a在内存中的地址:%d\n",*p); //地址使用%p表示
//实际上,当拿到一个变量的地址后,我们完全不需要再使用这个变量,而是可以通过它的指针来对其进行修改
int m = 9999,n = 6666;
swap(&m,&n);
printf("%d %d\n",m,n);
/**
* const类型的指针
*/
int a1 = 2,a2 = 3;
const int* g1 = &a1;
// *g1 = 20; //这里直接爆红,因为const标记的指针,所指地址上的值不允许发生修改
g1 = &a2; //但是指针指向的地址是可以被修改的
//我们来看另一个关键的。
int a3 = 4,a4 = 5;
int* const g2 = &a3;
// g2 = &a4; //这里直接爆红,因为g2是一个指针变量,所以它前面加const,意味着该指针不允许被修改它所指向的地址
*g2 = a4; //但是指针所指地址的值可以被修改
//当然也可以双管齐下
const int* const g3 = &a1; //此时意味着无论是指针所指的地址,还是指针所指地址的值都不允许被修改。
}
#include <stdio.h>
/**
* 指针与数组
* @return
*/
int main(){
char str[] = "Hello World";
char* p = str;
printf("%c\n",*p);
printf("%c",p[1]); printf(" %c\n",str[1]);
printf("第一个元素值为:%c,第二个元素值为:%c\n", *p, *(p+1)); //通过指针也可以表示对应位置上的值
// 比如我们现在需要表示数组中的第二个元素:
// * 数组表示法:str[1]
// * 指针表示法:*(p+1)
/**
*虽然写法不同,但是它们表示的意义完全相同,都代表了数组中的第二个元素,其中指针表示法使用了p+1的形式表示
* 第二个元素,这里的+1操作并不是让地址+1,而是让地址 + 一倍的对应类型大小,也就是说地址后移一个char类型
* 的长度,所以正好指向了第二个元素,然后通过 * 取到对应的值(注意,这种操作仅对数组是有意义的,如果是普通的变量,
* 虽然也可以通过这种方式获得后一个char长度的数据,但是,毫无意义)
*/
/**
* str[i] <--> *(p+i) 实际上就是可以相互转换的
*/
printf("——————————————————————————————————————————————————————————————————————————————\n");
/**
* 练习
*/
int arr[10] = {0,1,2,3,4,5,6,7,8,9};
int* q = arr;
printf("%d\n",*q); //数组的第一个元素
printf("%p\n",q); //数组的第一个元素的地址
printf("%d\n",q == arr); //都是数组首元素地址
printf("%d\n",*arr); //数组的第一个元素
printf("%p\n",&arr[0]); //数组的第一个元素的地址
printf("%d\n",*(q+1)); //数组的第二个元素
printf("%p\n",q+1); //数组的第二个元素的地址
printf("%d\n",*q + 1); //数组的第二个元素,这里注意 * 比 + 优先级要高
//当然,指针也可以进行自增或自减
int* g = arr + 2;
printf("%d\n",*g);
g++;
printf("%d\n",*g);
printf("——————————————————————————————————————————————————————————————————————————————\n");
/**
* 二维数组
*/
int brr[2][3] = {{1,2,3},{4,5,6}};
int* t = brr[0]; //因为是二维数组,注意这里要指向第一个元素,来降一个维度才能正确给到指针
//同理,如果这里是brr[1]的话,那么就表示指向二维数组中第二个数组的首元素
printf("%d = %d",*(t + 4),brr[1][1]); //这两种访问形式一样
printf("——————————————————————————————————————————————————————————————————————————————\n");
/**
* 多级指针(本质就是套娃)
*/
int n = 100;
int* l = &n; //指向普通变量的指针
//因为现在要指向一个int* 类型的变量,所以类型为int* 再加一个*
int** ll = &l; //指向指针的指针(二级指针)
int*** lll = ≪ //指向指针的指针的指针(三级指针)
printf("l = %p,n = %d",*ll,**ll);
}