指针

作者: jtsky | 来源:发表于2017-12-27 16:00 被阅读7次

    简介

    指针是一个值为内存地址的变量,不能赋常量值,必须要变量地址
    &:取址操作符
    *:取值操作符

    int main() {
        int a = 10;
        int* b = &a;//&是取址操作符
        printf("a变量的内存地址是:%p \n",b);
        printf("a变量内存中储存的值为:%d \n",*b);
        //*是取值操作符
        *b = 11;//修改a变量内存地址中所保存的值
        printf("修改后a变量的内存地址是:%p \n",b);
        printf("修改后a变量内存中储存的值为:%d \n",*b);
        printf("修改后a变量内存中储存的值为:%d \n",a);
        return 0;
    }
    

    输出的日志如下

    a变量的内存地址是:0061FF28
    a变量内存中储存的值为:10
    修改后a变量的内存地址是:0061FF28
    修改后a变量内存中储存的值为:11
    修改后a变量内存中储存的值为:11

    指针与数组

    数组就是一块连续的内存空间
    数组名就是这块连续内存空间的首地址

    num为一维数组
    num[i] <====> *(num +i) 两者等价

        double  score[5] = {98 ,97,65,43,25};
        double * ptr_score;
        ptr_score = score;
        for(int i=0;i<5;i++){
            printf("%.2lf\n",*ptr_score ++);
        }
    

    一个类型为T的指针移动,以sizeOf(T)为移动单位
    比如double类型的变量指针++每次移动8个字节

        double score[5] = {98.00, 97.00, 65.00, 43.00, 25.00};
        double *ptr_score;
        ptr_score = score;
    
        for (int i = 0; i < 4; i++) {
            printf("%.2lf\n", *(ptr_score++));
        }
    
        printf("%.2lf\n", *ptr_score);
    

    当数组指针移动后,再次打印的是当前指针一下个SizeOf(T)的值

    例子(数组逆序)

    int score[5] = {98, 97, 65, 43, 25};
        int *ptr_score_start = score; //数组首元素的指针
        int *ptr_score_end = score + 4;//数组末元素的指针
        int temp;
        while (ptr_score_start != ptr_score_end) {
            //首尾交换
            temp = *ptr_score_start;
            *ptr_score_start = *ptr_score_end;
            *ptr_score_end = temp;
            ptr_score_start++;
            ptr_score_end--;
        }
        for (int i = 0; i < 5; i++) {
            printf("%d\n", *(score + i));
        }
    

    二维数组与指针

    image.png

    二位数组的首地址:&a[0][0]
    使用指针访问二维数组中的元素

     int score[5][3] = {
                {1, 2, 3},
                {4, 5, 6},
                {7, 8, 9},
                {10, 11, 12},
                {13, 14, 15}
        };
    
        for (int i = 0; i < 5; i++) {
            for (int j = 0; j < 3; j++) {
                //因为一维数组中score[i]等价与 score + i
                //printf("%d \t", score[i][j]);
                //printf("%d \t", *(score[i] + j));
                printf("%d \t", *(*(score + i) + j));
            }
            printf("\n");
        }
    

    ((score + i) + j)取值的理解:
    因为score是一个二维数组,所以score就相当于一个指向score[0][0]的指针。如下:
    printf("%p \t %p\n", score, &score[0][0])=======》

    0061FEE4 0061FEE4

    所以当i=0时,(score + i)就相当于score对二维数组的第一行取值,*score就等价与score[0],所以它还是个数组,即 ((score + i) + j)成立。

    注意

    我们知道在一维数组中数组和指针是一一对应的,但是当我们对二维数组进行等价操作时会报如下错误:

    image.png
    必须定义指针类型,什么鬼?经过查找相关资料我们知道,其实ptr_score相当于子定义了一维空间,即ptr_score时指向行首部地址的指针,所以当我们用一维指针去操作二维数组时,就会报指针类型错误。那么我们要怎么改呢?
    如下所示:
    image.png
    就是我们在定义指针变量时去扩展它的维度就可以了

    数组和指针


    输出的日志如下:

    字符串常量的首地址:00405070
    字符数组的首地址:0061FF27
    字符指针的首地址是:00405070
    

    所以输出日志验证了上文的特性。

    相关文章

      网友评论

          本文标题:指针

          本文链接:https://www.haomeiwen.com/subject/ugydgxtx.html