C语言数组指针与指针数组,C语言的精华

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void func(char **p, int num)
{
    
    
    for (int i = 0; i < num; i++) {
    
    
//        printf("%s\n", p[i]);
//        printf("%s\n", *(p+i));
        printf("%s\n", *p++);
    }
}
int main(int argc, char *argv[], char** env)
{
    
    
#if 0
    struct student
    {
    
    
        int a;
        char b;
    };
    struct student *stud;
    struct student stu;
    stu.a = 222;
    *stud = stu;
    int arr[5] = {
    
    10,20,30,40,50};
    int str[5] = {
    
    100,200,300,400,500};
    /*数组指针指向数组首元素地址的指针,相当于一个二级指针,这个指针不可移动,它的长度和二维数组的列相同*/
    int(*p)[5] = &arr;//因为数组指针相当于二级指针,所以这里必须传入一维数组的地址
    printf("arr[1]=%d\n", *(p[0]+1));//p[0][1]
    int a = 1000;
    /*指针数组是一个数组,里面存储的是指向变量的指针,变量是指针数组类型的就行,它的长度的二维数组的行相同*/
    int *q[5] = {
    
    arr, str, &a, &stu.a};
    *(q[1]+2) = 1;
    printf("str[1]=%d\n", *(q[1]+1));
    *q[2] = 2000;
    printf("a=%d\n", *(q[2]+0));
    printf("arr[1]=%d\n", q[0][1]);
    printf("stu.a=%d,stud->a=%d\n", q[3][0], *q[3]);
    int num[2][5] = {
    
    {
    
    111,222,333,444,555},{
    
    666,777,888,999,1111}};
    /*第一种方法传入的是数组各元素的地址*/
    int(*ptr)[2][5] = &num;
    printf("num[1][4]=%d\n", ptr[0][1][4]);//第一个必须是0,第二个控制着行,第三个控制着列
    printf("num[0][3]=%d\n", *(ptr[0][0]+3));//第一个必须是0,第二个控制着行,+控制着列
    /*第二种方法传入的数组的各元素*/
    int(*ptr1)[5] = num;
    printf("num[0][3]=%d\n",ptr1[0][3]);
    printf("num[1][2]=%d\n", *(ptr1[1]+2));
#endif

#if 0
    char str1[10] = "hello";
    char str2[10] = "world";
    char str3[10] = "windows";
    char str4[10] = "linux";
    char str5[2][6] = {
    
    "12345","abcde"};
    printf("%u\n", sizeof (*str5) / sizeof (**str5));//求列长
    char x = 'a';
    char(*ptr)[6] = str5;
    printf("str5[0]=%s,str5[1]=%s\n", ptr[0],*(ptr+1));//*(ptr[0]+1)程序报错,(ptr[0]+1)=2345
    char(*p)[10] = &str1;
    printf("str1[10]=%s\n", *p);
    char *q[10] = {
    
    str1, str2, str3, str4, &x};
    printf("str2[10]=%s, x=%c\n", q[1], *q[4]);
#endif

#if 0
    /*二维数组也是线性存储的,通过数组指针也可以实现对一维数组的二维访问方式*/
    int arr[12] = {
    
    1,2,3,4,5,6,7,8,9,10,11,12};
    int(*p)[4] = (int(*)[4])arr;
    for (int i = 0; i < sizeof (arr) / sizeof (int[4]); i++) {
    
    
        for (int j = 0; j < 4; j++) {
    
    
            printf("%d\t", p[i][j]);
        }
    putchar(10);
    }
#endif

#if 0
    /*a是一个二维数组,&a[4][2]就是取这个元素的地址,因为a是5个元素一行,所以&a[4][2]也就是第5行的第3个元素,
     * 而p是4个元素一行,&p[4][2]也就没&a[4][2]的地址高,而它们之间正好间隔4个元素,结果就是-4*/
    int a[5][5];
    int (*p)[4] = a;
    printf("%d\n", &p[4][2] - &a[4][2]);
#endif

#if 0
    int a[10] = {
    
    0,1,2,3,4,5,6,7,8,9};
    printf("&a[9]=%p\t &a[4]=%p\n", &a[9], &a[4]);
    printf("&a[9]=%d\t &a[4]=%d\n", &a[9], &a[4]);
    printf("(int)&a[9]=%p\t (int)&a[4]=%p\n", (int)&a[9], (int)&a[4]);
    printf("(int)&a[9]=%d\t (int)&a[4]=%d\n", (int)&a[9], (int)&a[4]);
    printf("&a[9] - &a[4]=%d\n", &a[9]-&a[4]);//5
    printf("(int)&a[9] - (int)&a[4]=%d\n", (int)&a[9]-(int)&a[4]);//20
    printf("(int)&a[6] - (int)&a[0]=%d\n", (int)&a[6] - (int)&a[3]);//12
#endif

#if 0
    int a[5] = {
    
    1,2,3,4,5};
    /*a在内存中的布局是01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00,小端是这样,大端反过来*/
    int *p = (int*)(&a + 1);
    int *q = (int*)((int)a + 1);
    printf("p=%#p\t q=%#p\n", p[-1], *q);
    /*p[-1] = *(p-1),(int*)((int)a+1)a被强制转换成了int型,所以a+1=2,然后2再次被强制转换成了(int*),
    那么就往前移动了4个字节,也就是一个int的距离,此时q指向了02,又因为q的类型是int*,所以取q的值时,连带
    02后面的6个0就一起被取了出来,所以显示是0x02000000*/
#endif
/*二级指针和一维数组、二维数组都没关系,和指针数组有关系*/
#if 1
    /*pa的本质还是数组,pa里面每个元素都是char*的,对pa[0]取地址就是char**了*/
    char *pa[] = {
    
    "Orcale", "IBM", "Facebook", "Tencent", "GOOGLE", "HuaWei", NULL};//在指针数组的最后加一个NULL
//    func(pa, sizeof (pa)/sizeof (pa[0]));
    char **q = pa;
    while (*q) {
    
    
        printf("pa=%s\n", *q++);
    }
#endif

#if 0
    char a[] = "china";
    char *p = a;
    int i = 0;
    while (*p) {
    
    
        printf("a[%d]=%c\n", i, *p++);
        i++;
    }
#endif

#if 1
//    for (int i = 0; i < argc; i++) {
    
    
//        printf("%s\n", argv[i]);
//    }
//    while (*argv) {
    
    
//        printf("%s, %d\n", *argv++);
//    }
//    while (*env) {
    
    
//        printf("%s\n", *env++);
//    }
//    argv[0] = "123";
//    argv[1] = "abc";
//    printf("argv[0]=%s\nargv[1]=%s\n", argv[0], argv[1]);
#endif
    return 0;
}
/*一维数组名等价于1级指针,对一维数组名取地址就等价于数组指针,并不是二级指针*/

指针数组和数组指针,C语言一定要掌握的知识点。

猜你喜欢

转载自blog.csdn.net/cp_srd/article/details/105497379