• C语言-数组


    概念

    分类

    根据数据类型的不同:

    • 数值数值
    • 字符数组
    • 指针数组
    • 结构数组

    概念

    C语言数组在存储时,是行优先
    多维数组下,如二维数组,可以看成是嵌套:一个数组可以作为外部数组的一个元素
    C语言数组是静态的,不能插入或删除元素(数组一旦被定义,占用的内存空间就是不可改变的,但是可以修改和读取数值),如果要改变一个数组,就要再造一个数组

    数值数组

    创建数组:赋值个数小于开辟的内存空间,且剩余的元素会被初始化为0,对于整型,初始化为0;对于浮点型,初始化为0.0

    int a[10]={1,2,3};
    // 只能以循环的方式进行输出
    for (int i=0;i<10;i++){
        printf("%d\n",a[i]);
    }
    
    // 方法2
    int a[]={1,2,3,4}; // 自动计算需要开辟的内存空间
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    多维数组

    创建数组:可以按行创建,也可以连续创建。部分赋值创建的时候,其他赋值元素默认初始化为0(注意部分赋值和完全不赋值随机初始化的区别,完全不赋值随机初始化的时候不是0)
    如果是全部赋值,第一维度可以不写
    嵌套理解

    // 按行创建
    int a[2][3]={{1,2,3},{4,5,6}};
    
    // 按连续内存创建
    int a[2][3]={1,2,3,4,5,6};
    
    // 部分赋值
    int a[2][3]={{1},{2},{3}};
    int a[2][3]={{0,1},{0,1,2},{3}}
    
    // 第1维度自动推导
    int a[][3]={1,2,3}
    
    int a[][3]={1,2,3};
    for (int i=0;i<1;i++){
        for (int j=0;j<3;j++){
            printf("%d\n",a[i][j]);
        }
    }
    
    // 嵌套理解
    a[3][4] 中 a[0]是一个数组
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    多维数组的指针

    https://blog.csdn.net/L_fengzifei/article/details/126411708

    见下例子

    int a[1][3]={1,2,3};
    for (int i=0;i<1;i++){
        // for (int j=0;j<3;j++){
        //     printf("%d\n",a[i][j]);
        // }
        printf("%p\n",a[i]);
        printf("%p\n",&a[i][0]); // &a[i][0] 与a[i] 等价
        printf("%d\n",a[i][0]);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    数组与地址

    int c[10]={1,2,3};
    printf("%p\n",&c);
    printf("%p\n",c); // 数组名也是地址
    printf("%p\n",&c[0]); // 也是数组第一个元素的地址
    
    • 1
    • 2
    • 3
    • 4

    数组与指针

    https://blog.csdn.net/L_fengzifei/article/details/126411708

    问题

    下面会输出十个数,并没有发生越界???

    int a[4];
    // 只能以循环的方式进行输出
    for (int i=0;i<10;i++){
        printf("%d\n",a[i]);
    }
    
    return 0;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    字符型数组

    对于字符型数组,赋值个数小于开辟的内存空间,则初始化为"\0"printf("%c","\0")打印不出来任何东西

    字符数组就是字符串
    c语言中没有字符串类型,所以用 字符数组存放一个字符串

    char str[10]={0} // 默认初始化为\0
    
    // 一维
    char s[10];
    
    // 多维
    char s[2][3];
    
    // 部分赋值
    char c[20]={' ','2'};
    
    // 全元素赋值,自动推导长度
    char d[]={'h','e',...};
    
    // 注意
    char s[10];
    s="hello world"; // 这种方式不行
    s[0]='0'; // 只能是这种方式
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    字符串

    字符串 其实是字符数组
    字符数组就是字符串
    c语言中没有字符串类型,所以用 字符数组存放一个字符串
    可以通过索引获得元素字符
    注意:,下面创建的字符串,具有读写权限

    char s[30]={"hello world"}; // 等价于char s[30]={'h','e',...};
    
    // 其他常用方式
    char s[10]="hello world";
    
    char s[]={"hello world"};
    char s[]="hello world";
    
    // 索引
    char a[10]="hello";
    printf("%c\n",a[1]);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    长度

    strlen计算不包括结尾的\0
    sizeof计算包含结尾的\0

    #include 
    char str[]="hello";
    long len=strlen(str);
    printf("%ld\n",len);
    
    // sizeof 要么等价于实现开辟的内存空间,要么要包含`\0`
    char a[10]="hello";
    printf("%d",sizeof(a));
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    \0

    \0不能显示,也没有控制功能
    字符串以\0结尾,注意字符数组不以\0结尾
    字符串逐个扫描,一旦遇到\0结束处理

    "string"会在字符串自动在末尾添加\0
    字符串的字符个数,要包括后面结尾的\0
    创建的时候,要为\0,多开辟一个内存空间,所以总数要比字符串+1

    // 创建字符串数组,下面这种方式只能逐个元素创建
    // 当创建的字符个数小于开辟的数量,剩下的为随机初始化的内容,有可能并不是\0,注意随机初始化和部分初始化的
    // 所以输出的可能字符个数可能大于30与,因为printf直到\0的时候才会结束输出
    char s[30];
    chr c;
    int i;
    for (c=65,i=0;c<=90;c++,i++){
    	s[i]=c;
    }
    printf("%s\n",s)
    
    // 手动添加\0
    // \0 的ASCII编码值是0
    // 下面两个等价
    s[i]=0; 
    s[i]='\0';
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    字符串与地址
    char a='c';
    printf("%p\n",&a);
    printf("%p\n",a); // 这两个地址不同
    
    char b[10]="hello";
    printf("%p\n",&b); 
    printf("%p\n",b); // 字符串的名字是地址
    printf("%p\n",&b[0]); // 也是字符串第一个元素的地址
    
    int c[10]={1,2,3};
    printf("%p\n",&c);
    printf("%p\n",c); // 数组名也是地址
    printf("%p\n",&c[0]); // 也是数组第一个元素的地址
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    字符串与指针

    https://blog.csdn.net/L_fengzifei/article/details/126411708

    指针数组

    数组中所有元素保存的都是指针,就叫做指针数组
    dataType *arr[]dataTye* (arr[])
    表明是一个数组,每个元素的类型都是dataType*
    注意 指针数组和二级数组的区分

    int* arr[3]={&a,&b,&c};
    int** p=arr; // 定义一个指向指针数组的指针,相当于(int*)* p=arr
    
    
    char* str[2]={"hello","world"};
    printf("%s\n",str[0]); // 输出"hello",char* s="hello";
    
    //下面的方法更好理解
    char* s1="hello";
    char* s2="world";
    char* s[2]={s1,s2};
    
    /*
    char *s="hello";
    
    char *s;
    s="hello";
    */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    结构体数组

    数组中每个元素都是结构体

    struct stu{
    	char* name;
    	int num;
    }class[5];
    
    // 声明的时候初始化
    struct stu{
    	char* name;
    	int num;
    }class[5]={
    	{"li",1},
    	{"w",2}
    };
    
    // 声明的时候初始化,自动推断元素个数
    struct stu{
    	char* name;
    	int num;
    }class[]={
    	{"li",1},
    	{"w",2}
    };
    
    // 可以在结构体外,创建结构体数组
    struct stu class[]={
        {"li",2},
        {"wang",3}
    };
    
    // 访问数据
    class[0].name;
    class[1].num=2; //修改
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
  • 相关阅读:
    docker 简单在线安装教程
    举报即有机会解锁CSDN限定勋章|2022上半年CSDN社区治理数据公布
    STM32实现将printf重定向到串口的3种方法
    力扣200岛屿数量解法3种
    【Axure教程】中继器制作树元件
    互联网Java工程师面试题·Spring篇·第七弹
    Java面试题-Redis-第四天(线程模型一)
    nodejs如何实现URL的拆分
    Vue2和Vue3的emit、props、watch等知识点对比
    【P60】JMeter Jtl 文件的 html 格式输出
  • 原文地址:https://blog.csdn.net/L_fengzifei/article/details/126382264