C语言指针(基础)

#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 = &ll;  //指向指针的指针的指针(三级指针)

    printf("l = %p,n = %d",*ll,**ll);

}

在这里插入图片描述

  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值