C语言多级指针

 
C语言的指针比较灵活,可以将任何一个无符号数转换为一个指针并使用。
今天犯了一个错误:
 
 
 
int data[][2] = {{1, 6}, {4, 7}, {2, 11}, {3, 1}, {17, 32}, {13, 16}, {21, 23}, {48, 14}, {16, 66}, {27, 15}};
int** p = data;
printf("%d\n",p[2][1]);//错误代码:运行时越界异常。原因:没有指清楚维度,要想p[2][1]这样使用就必须指清楚维度
 
以上错误来源于下面的一次实践代码中:
 
 
int comp2(const void *a, const void *b)
{
    //return ((int **)a)[0][0] - ((int *)b)[0][0]; //错误代码
    return ((int *)a)[0] - ((int *)b)[0];
}
int data[][2] = {{1, 6}, {4, 7}, {2, 11}, {3, 1}, {17, 32}, {13, 16}, {21, 23}, {48, 14}, {16, 66}, {27, 15}};
qsort(data, 10, sizeof(data[0]), comp2);
 
int *和int** (或者维度更高的指针如int****)在使用时:int*为一维的,强转后(int *)a)[i]这样使用,并不一定出错,主要是看下标i是否越界;但是int**或者维度更高的指针就不行了,n维的指针其n-1维的范围需要明确指出来,剩下的第n维就可以“看做”int*
因此,下面代码合法
 
int comp1(const void* a, const void* b)
{
    return *((int*)a) - *((int*)b);
}
//普通的二维数组
int comp2(const void *a, const void *b)
{
    return ((int *)a)[0] - ((int *)b)[0];
}
//malloc申请的二维数组
int comp3(const void* a, const void* b)
{
    //这里不一定是2,还是要看具体的维度
    return ((int (*)[2])a)[0] - ((int (*)[2])b)[0];
}
//malloc申请的二维数组
int comp4(const void* a, const void* b)
{
    int *ap = *(int **)a;
    int *bp = *(int **)b;
 
    if (ap[0] == bp[0])
    {
        return ap[1] - bp[1];
    }
    else
    {
        return ap[0] - bp[0];
    }
}
int main()
{
    int data[][2] = {{1, 6}, {4, 7}, {2, 11}, {3, 1}, {17, 32}, {13, 16}, {21, 23}, {48, 14}, {16, 66}, {27, 15}};
    int i = 0;
    int *b, **a;
    a = (int**)malloc(10 * sizeof(int*)); //这里是对int*来分配。
    for (i = 0; i < 10; i++)
    {
        a[i] = malloc(2 * sizeof(int));
        a[i][0] = data[i][0];
        a[i][1] = data[i][1];
    }
    qsort(a, 10, sizeof(a[0]), comp3);
    for (i = 0; i < 10; i++)
    {
        printf("a %d %d\n", a[i][0], a[i][1]);
    }
    qsort(data, 10, sizeof(data[0]), comp2);
    for (i = 0; i < 10; i++)
    {
        printf("data %d %d\n", data[i][0], data[i][1]);
    }
    for (i = 0; i < 10; i++)
    {
        free(a[i]);
    }
    return 0;
}
这里comp1 comp2 comp4都是使用转换为1维指针巧妙回避了维数问题
 
明天了维数这个东西,指针便可以如下灵活自如的运用:
实质上就是1维到n为的变换游戏
 
#include<stdio.h>
int main()
{
    int data[][2] = {{1, 6}, {4, 7}, {2, 11}, {3, 1}, {17, 32}, {13, 16}, {21, 23}, {48, 14}, {16, 66}, {27, 15}};
    printf("%d\n", ((int(*)[2][2])data)[1][1][0]);
    printf("%d\n", ((int(*)[2][2])data[0])[1][1][0]);
    printf("%d\n", ((int(*)[2][2])(&data[0][0]))[1][1][0]);
    printf("%d\n", ((int(*)[2][3])data)[1][1][0]);
    printf("%d\n", ((int(*)[2][3])data[0])[1][1][0]);
    printf("%d\n", ((int(*)[2][3])(&data[0][0]))[1][1][0]);
    return 0;
}
运行结果:
3
3
3
32
32
32
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
posted @ 2017-05-08 15:54  Cloud2020  阅读(93)  评论(0)    收藏  举报