《C语言学习记录9》数组入门

基本概念:
逻辑: 一次性定义 多个 相同 类型 的变量,并把他们的内存统一分布在 一片连续的内存空间(顺序
存储)
语法:
1 类型 数组名 [ 元素个数 ] ;
2 int arr [10];

定义与初始化:
 int arr [3] ; // 定义了一个数组名为 arr 元素个数为 3 ,并没有初始化,他的值为随机值
 int arr1 [5] = {0} ;// 定义数组并初始化为0 , 不完整初始化,未初始化部分会被系统自动初始化为 0
 int arr2 [5] = {1,2,3} ; // 不完整初始化, 前面三个元素的值分别为123,但是后面两个自动设置为 0 
 int arr3 [5] = {1,2,3,4,5} ; // 完全初始化

 char c = 'a' ;
 char arrch[6] = {'a','b','c','d' , '\0'}; // 有结束符因此为字符串数组
 char arrch[4] = {'a','b','c','d' , '\0'}; // 无法存入结束符因此为字符数组
 char arrch[6] = "abcd"; // 双引号的数据默认是字符串格式的因此带有结束符
 char arrch[4] = "abcd"; // 无法存入结束符因此为字符数组

 int arr4 [5] = {1,2,3,4,5,6,7,8} ; // 在当前的编译器中后面超出的6.7.8会被直接丢弃
 int arr5 [ ] = {1,2,3,4,5,6,7,8} ; // 定义的时候可以省略数组的元素的个数不写,但是要求必须有初
 int arr6 [ ] ; // [错误] 数组在定义的时候必须要确定他的大小
 int arr7 [ 0 ] ; // 允许 数组的大小为 0 【零长数组】--> 放在结构体作为最后一个成员有用
注意:
数组在定义的时候必须确定他的大小长度(元素的个数)。可以 省略元素个数 不写,但是 必须
写初始化 , 如果 不想写初始化 那就 必须写数组元素个数
数组元素的引用:
数组的下标(偏移量)
概念: 数组的下标也称为某一个元素的偏移量。
解读:数组名字代表的是 该数组的入口地址 。后面的某一个元素就通过 偏移量 来访问,可以理解为是数组的第几个元素。偏移量从 0开始,因此数组的下标也是从0开始。 下标的最大值 应该为数组元素的个数 -1 。
 int arr[10] = {1,2,3,4,5,6,7,8,9,0};
 arr [ 5 ] = 250 ; // 访问arr数组的第5个元素并把他的值改成 250
 printf( "%d\n" , arr[5] );
练习:
尝试定义一个数组,并访问数组中的每一个元素(循环体)。
#include <stdio.h>

int main()
{
    int arr[7]={1,2,3,4,5,6,7};

    for(int i=0;i<7;i++)
    {
        printf("arr[%d]=%d\n",i,arr[i]);
    }
    
    return 0;

}
注意:
数组的下标是从0 开始的, 因此最大的下标应该等于实际元素个数 -1 。
数组是C语言中唯一一个允许越绝访问的方式, 但是越界之后的值不可预测。
实例:
1、完全不初始化, 以下代码输出的数组的值为随机值
#include <stdio.h>
int main()
{

    int arr[10];

    for(int i=0;i<10;i++)
    {
        printf("arr[%d]=%d\n",i,arr[i]);
    }
    
    return 0;

}

 2、不完全初始化,以下代码输出的值前4个为初始化的值,后面则为0

#include <stdio.h>

int main()
{
    int arr[8]={1,2,3,4};

    for(int i=0;i<8;i++)
    {
        printf("arr[%d]=%d\n",i,arr[i]);
    }
    
    return 0;
}

 

 3、越界访问,以下代码中,数组的合法元素个数为 8 个 ,但是循环体中有13个需要输出, 那么超出部分则输出随机值

#include <stdio.h>
int main()
{
    int arr[8]={1,2,3,4,5,6,7,8};

    for(int i=0;i<13;i++)
    {
        printf("arr[%d]=%d\n",i,arr[i]);
    }
    
    return 0;
}

4、数组越界初始化,以下代码中注意数组的大小设置为8 ,因此该数组理论上只能存入初始化语句中的前8个数据, 后面的会被编译器直接丢弃 , 因此输出超过数组范围的数据为随机值

#include <stdio.h>
int main()
{
    int arr[8]={1,2,3,4,5,6,7,8,9,10,11,12,13};

    for(int i=0;i<13;i++)
    {
        printf("arr[%d]=%d\n",i,arr[i]);
    }
    
    return 0;
}

数组的尺寸:
数组的尺寸取决于 元素的个数 以及 数据的类型
如何计算数组的大小:
sizeof (数组名) ——————> 计算的是整个数组的大小 元素类型* 元素个数
sizeof(arr) ;
printf("sizeof(arr3):%ld\n" , sizeof(arr3 ) );如何计算数组元素的个数: 
元素个数 = 整个数组大小 / 某个元素的大小
2 int num = sizeof(arr) / sizeof(arr[0]) ;
如何得出数组的元素下标的最大值:
1 元素最大下标 = 整个数组大小 / 某个元素的大小 - 1
2 int num = sizeof(arr) / sizeof(arr[0]) - 1;
实例:
1 int arr [] = { 1 , 2 , 3 , 4 , 54 , 6 , 7 , 325 , 3 , 4 , 5 } ;
字符数组:
概念: 字符数组是一个专门用来存放字符类型输数据的数组。
定义、初始化:
char TieZhu [ 10 ] ; // 完全没有初始化,他的值为随机值
char TieZhu [ 10 ] = {0}; //部分初始化 , 0 表示字符的ASCII值 ,char a = 97
char TieZhu [ 10 ] = {'\0'}; // 部分初始化,‘\0’表示字符
char TieZhu [ 10 ] = {'0'}; // 部分初始化,‘0’表示字符 ASCII 为 48
char TieZhu [ 10 ] = {"Hello"}; // 字符串数组
char TieZhu [ 10 ] = {'H' , 'e' , 'l' ,'l' , 'o'}; // 字符数组

char TieZhu [ ] = {"Hello"}; // 字符串数组
char TieZhu [ ] = {'H' , 'e' , 'l' ,'l' , 'o'}; // 字符数组
元素引用:
练习:
给定一个字符串 "Hello World!!!" 通过代码来计算该字符串的 长度
法一:

#include <stdio.h>
int main()
{
    char arr2[] = "Hello World!!!";//字符串是以'\0'作为结束符
    int i;
    for (i = 0; i < sizeof(arr2)/sizeof(arr2[0]); i++)
    {
        if (arr2[i] == '\0')
            break;//跳出循环体
    }
    printf("arr2=%d\n",i+1);
    return 0;
}


法二:

#include <stdio.h>
int main()
{
    char arr2[] = "Hello World!!!";
    int i=0;
    while (arr2[i]!='\0')
    {
        i++;
    }
    
    printf("arr2=%d\n",i+1);
    return 0;
}

拓展从键盘获取一个用户随机输入的一句话然后程序计算长度 .
#include <stdio.h>
int main()
{
    char arr2[1024];
    printf("从键盘输入一句话:\n");
    //scanf("%s",&arr2);scanf不能接受空格、制表符Tab、回车等;而gets能够接受空格、制表符Tab和回车等;故此题用gets 输入函数。
    gets(arr2);
    printf("%s\n",arr2);
    int i=0;
    while (arr2[i]!='\0' || arr2[i]==' ')
    {
        i++;
    }

    printf("arr2=%d\n",i+1);
    return 0;
}

字符串长度计算的函数:
strlen 的作用: 用来计算字符串的长度并返回长度
注意: 该函数计算字符串长度的时候遇到结束符即停止,并 结束符不计入长度内
 头文件:
 #include <string.h>
 函数原型:
 size_t strlen(const char *s);
 参数分析:
 s --> 需要计算长度的字符串的入口地址
 返回值:
 成功 返回该字符串的长度(不包含结束符)
注意:
msg = "Even"; // [ 错误 ] 不允许对数组名直接赋值

// 初始化后 如果需要对数组进行重新复制,只能一个一个元素进行赋值
msg[0] = 'E'; 
msg[1] = 'v';
msg[2] = 'e';
msg[3] = 'n';

int arr[] = {1,2,3,4,5}; // 初始化语句允许进行整体赋值
arr = {6,7,8,9,10} ; // 离开初始化语句后不允许的数组进行整体赋值,只能也一个一个元素地赋值
//也可以使用循环体进行赋值

越界访问:
当一个数组的大小定义的时候设置为10 ,但是访问该数组的时候 超过了原本申请的大小10 甚至
更多的时候就称为越界访问。
越界访问一定会出问题吗?
不一定!!
越界访问 不一定是非法 的。
非法访问用是越界的。
练习:
假设给定一个整型数组 { 6 , 4 , 27 , 23 , 6 , 56 , 1 , 3 } , 尝试使用排序算法将他进行重新排序后
输出。
冒泡排序:
#include <stdio.h>

int main()
{
    int arr1[]={1,2,1234,34,54,6,86,8,8,23,214};
    int i,j,temp=0;
    for(i=0;i<sizeof(arr1)/sizeof(arr1[0])-1;i++)//外循环,记录没次比较后所减少的比较次数
    {
        for(j=0;j<(sizeof(arr1)/sizeof(arr1[0])-1-i);j++)//内循环,进行两两比较
        {
            if(arr1[j]>arr1[j+1])
            {
                temp=arr1[j+1];
                arr1[j+1]=arr1[j];
                arr1[j]=temp;
            }
        }
    }

    for(int i=0;i<sizeof(arr1)/sizeof(arr1[0]);i++)//输出比较后,数组所存储的数值
    {
        printf("%d ",arr1[i]);
    }
    return 0;
}

拓展:
从键盘直接输入数据,并完成排序。
作业:
1、 使用数组的知识点尝试实现把一个字符串数组进行翻转 输出
#include <stdio.h>
int main()
{
    char arr2[1024];
    printf("从键盘输入一句话:\n");
    gets(arr2);
    printf("%s\n",arr2);
    int i=0;
    while (arr2[i]!='\0')
    {
        i++;
    }
    printf("arr2=%d\n",i+1);
    for(;i>=0;i--)
    {
        printf("%c",arr2[i]);
    }
    printf("\n");
    return 0;
}

3. 键盘随机输入一串字符串,程序检查并去掉相邻的重复字符后输出
1 输入: hello google
2 输出: helo gogle
二维数组
指针
笔试题的注意事项:
不/考虑 空间(内存) 的问题
是否可以使用第三个变量 (是否可以创建新的变量)
是否可以使用第二个数组(可不可以在原有基础上创建新的数组)
链表.......
不考虑 效率 的问题
拓展如何在标准输入字符串时输入空格以及TAB 按键:
默认情况下 空格 以及 Tab 按键会作为scanf 的结束标记。
方法1 :
正则表达式:
scanf("%[^\n]" , msg) ;
%[^\n] --> 表示在输入数据的时候只要不是换行符 \n 都允许

 

方法2 :

 

不使用scanf ,改为 fgets 
功能:
从指定的某一个文件中获取一条字符串(以 \0 、 \n 为结束符)
头文件:4 #include <stdio.h>
函数原型:
char *fgets(char *s, int size, FILE *stream);
参数分析:
s --> 获取到的字符串所存放的内存地址(数组名)
size --> 表示你希望获取的字符串的最大尺寸(数组的大小尺寸)
stream --> 从那个文件中获取
返回值:
成功 返回指针s (数组的入口地址)
失败 返回NULL 
练习:
用户从键盘随意数组字符或数字,程序计算得出用户输入的所有小写字符、空格、大写字符、符号
的数量
1 输入: Hello Even GZ2207 @
2 输出:
3 空格: 2
4 小写字符: 7
5 大写字符: 4
6 数字: 4
7 符号: 1
多维数组:
概念: 如果一个数组的元素也是一个数组那么该数组就是多维数组(二维数组)

语法:
1 int arr [3] [ 5 ] ;
解读:多维数组如何定义以及初始化:
// 定义一个数组名为 arr 他一共有3个元素,
// 每一个元素都是一个数组,该数组有5个元素每一个元素都是整形的。
int arr [3][5] ;
int arr [3][5] = { 1,2,3,4,5,6,7,8,9,10 }; // 该数组的元素有 3×5个 因此该初始化未完全,未初
int arr [3][5] = { {} , {} , {1,2,3,4,5} };
多维数组的引用:
int arr [3][5] = { 1,2,3,4,5,6,7,8,9,10 };
printf("arr[0][3]:%d\n" , arr[0][3]);
问题: int arr [100][25] ; 请输出第 365个元素的值???
365 / 25 ---> 得出第几组 N
365 % 25 --> 得出在该组中的偏移量 M - 1
arr[N][M] ;
拓展:
临界值的问题
1 int arr [ 3 ][ 5 ] = { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 };
2 如何写出第十个数据的值??

 

数组的万能拆解方法:
任意一个数组不管有多复杂都可以通过该方法来拆解分析
第一部分: 说明数组的名字已经他的元素个数
第二部分: 说明该数组的元素是什么类型的数据
1 char arr [ 3 ][ 5 ][ 6 ] ; // 第一部分 arr [3] , 第二部分 char [5][6]
2 int ( * arr [ 3 ]) ( int , float ) ; // 第一部分 arr[3] , 剩下的是第二部分
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值