成长之路---C语言笔记(构造类型之数组)

简介: 成长之路---C语言笔记(构造类型之数组)

C语言具有丰富的数据结构,除了基本数据类型,如整型(int)、字符型(char)、实型(float和double)外,还有各种构造类型,如数组,指针,结构体等。在前面的学习中我们已经初步的学习了一些基本数据类型的使用方法,现在让我们来了解一下各种构造类型吧:


数组


在我们学习C语言过程中常常遇到需要处理大量的相关数据的问题,如果我们为每一个数据都定义一个独立的变量用于记录,这样虽然可以解决问题,但会造成变量过多,各数据之间并无联系,没有整体概念,不变管理等问题,为了解决这些问题C语言中定义了数组的概念


数组是指一系 列具有相同类型的有序数据元素的集合,这些数据元素在内存中按颗序连续存放。数组是一一个整体,一 次性定 义一组相同类型的变量, 每个变量没有单独的名字,而是使用数组名加变量在数组中的位置来进行访问。一维数组是最简单的数组,C语言支持一维数组和多维数组。


一维数组


1.一维数组的定义:


数组定义中的类型名可以是基本数据类型或构造数据类型。数组名是用户自定义的标识符,要符合标识符的定义规范。方括号中常量表达式的值必须大于等于1.表示数组的长度,即数组中包含的元素个数。


类型名 数组名 [常量表达式];


例如:我们声明了一个一维数组变量 int arr[10];其中它含有10个int 类型的变量而arr第一个数据元素是从下标为0开始的即(arr[0]),第二个数据元素是arr[1],以此类推,第10个数据元素是arr[9]。


2.数组元素在内存中的存储:


按顺序连续存放


arr[0]

......

arr[9]



注:下标用于引用数据元素,与数组定义时的常量表达式含义不同,后者用于声明数组长度,数组长度i是固定的在后续操作中不允许改变。


3.一维数组的引用:


数组元素只能逐个访问,不能一次性整体引用。数组元素可以通过数组名加下标进行访问


数组名[下标];


注:下标只能为整型或整型表达式,下标值从0开始,不得超过数组长度-1,否则将造成数组溢出导致不可预测的情况发生。


4.一维数组得初始化:


在定义数组的同时我们还可以为数组元素赋予初值,初值列表用花括号“{}”括起来。


类型名 数组名[常量表达式]={值...值};
例如:int a[5]={1,2,3,4,5};


注:


1.初值列表中的值的数目不可大于数组长度,当初值列表中的元素个数小于数组长度时,只对数组前面的部分元素赋值,剩下未指定初值的数自动赋值为0。


2.只能逐个为数组元素赋初值(除0外),诺对数组的全部元素赋初值可以不指定数组长度。


int a[10]={0};
int a[]={1,2,3,4,5};//这都是可行的


3.诺数组定义在函数体外,则数组元素均初始化为0,诺数组定义在函数体内则使用这些元素必须赋予初值。


4.除初始化外,不能使用花括号列表的形式为元素赋值。


这里我引用斐波那契输出前20位数举例:


#include<stdio.h>
#define N 20
void main() {
    long int a[N];
    int i;
    a[0] = a[1] = 1;
    for (i = 2; i < N; i++) {
        a[i] = a[i - 1] + a[i - 2];
    }
    for (i = 0; i < N; i++) {
        printf("%d ", a[i]);
        if ((i + 1) % 5 == 0) printf("\n");
    }
}


c5dbb3d67d2a64622bc0bdf934f256d7_a6b803baf4a9a4ae9e25e7f89953a102.png


二维数组


一维数组只有一个下标,可以看作一行连续的数据。C语言允许构造多维数组。多维数组元素有多个下标,以确定它在数组中的位置。多维数组其实就是数组的数组。二维数组是多维数组最简单的形式,而多维数组可由二维数组类推得到。


1.二维数组的定义:


第一维,即第一个方括号内的值通常称为行(ROW),第二维,即第二个方括号内的值通常称为列(Colomn)。


类项名 数组名[常量表达式][常量表达式];


以二维数组int a[3][5];为例:


数组a含有3个数组元素,每个数组元素内含有5个int型元素,那么数组a整体共有15(3x5)个整型元素。这个例子可以分成两部分加以理解,首先a是一个数组,内含3个元素(图7-2中的加粗部分),即a[0]~a[2],每个元素的类型是int[5], 也就是每个元素本身都是一个含有5个int元素的数组: a[0]是一 个数组, 其第1个数据元素是a[0][0],第2个数据元素是a[0][1]。



a[0][0]

a[0][1]

a[0][2]

a[0][3]

a[0][4]

a[1][0]

a[1][1]

a[1][2]

a[1][3]

a[1][4]

a[2][0]

a[2][1]

a[2][2]

a[2][3]

a[2][4]



2.二维数组在内存中的存储:


二维数组在概念上是二维的,但在计算机内部,一维数组是按顺序连续存储的,是线性结构。C语言采用按行存储方式,即先按存放第1行元素,再接着存放第2行元素。对于一个m行n列的二维数组a[m][n],假设,的第一个 元素a[0][0]的存储位置为LOC(a[0][0]),每个数组元素占用的存储单元为t字节,那么数组元素al[i][j]的地址可以按以下公式计算:LOC(a[i][j])= LOC(a[0][0])+(i*n+j)*t


3.二维数组的引用:


对二维数组元素进行访问,必须指明行下标和列下标,行下标指出的是哪个内部数组,列下标则在内部数组中指定相应元素。下标值应为整型常量或整型表达式。


数组名 [行下标][列下标];
b[2][3]=1;//数组元素被赋值
b[2][3]=b[1][0]+b[i][j];//数组元素参与运算
printf("%d",b[2][3]);//輸出数组元素的值


与一维数组类似,要确保行下标值和列下标值不越界,二维数组也不能整体赋值,需要以次访问各元素来赋值。


4.二维数组的初始化:


(1)分行初始化


对二维数组的初始化建立在一维数组初始化的基础上,因为二维数组的每一行是一个一维数组,因此可以按行初始化,有几行就使用几个初始化列表。


int a[3][4]={{0,1,2,3},
{4,5,6,7},
{5,6,7,8}
}


(2)将所有初值写在一个大括号内,可以按行连续赋初值,只保留最外面的一对花括号。


int a[3][4]={0,1,2,3,4,5,6,7,8};


(3)只对部分元素赋值,与一维数组的初始化类似,二维数组的初始化可以只为部分元素赋初值,剩下的元素值为0。


int a[3][4]={{0},{1},{2}};


如果省略了内部的花括号,且给出的初值个数不足,那么将按顺序逐步进行初始化,剩下没有初值的元素初始化为0。


(4)省略数组行数


如果给出了全部元素的初值,那么第维的长度可以省略, 但第二滩的长度 不能省略。


int a[[4]=10, 1.2.3.4.5.6,7,8.9.10,11);


编译器会根据元素总个数和列数计算出行数。上述代码的效果与以下代码等价:


int a[3][4]=(0.1,.2.3.4,5.6,7.8,9.10, 1);


如果在省略行数的情况下只对部分元素赋初值,那么应分行赋初值,不能省略嵌套的括号.


这里我引用生成杨辉三角为例:


//此代码实现的是输出杨辉三角前10行
#include <stdio.h>
int main()
{
    int a[10][10];
    int i,j;
    for (i=0;i<10;i++)
    {
        for (j=0;j<=i;j++)
        {
            if (j==0 || i==j) a[i][j]=1;      //无规律则直接赋值
            else a[i][j] = a[i-1][j]+a[i-1][j-1];      //有规律直接找规律赋值
            printf("%d\t",a[i][j]);
        }
        printf("\n");
    }
    return 0;
}


7a8bb61a8516097e44e2905adae1bc53_c05769573b7508171a265012db5b90b9.png


今日练习


给你⼀个 m ⾏ n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素(难度 有点⼤,需要⼀定的逻辑思维能⼒,每次都需要考虑好边界条件)


40fdb6ffce1f9b8511b2df605f160a2e_2cb619ca370a81db95f1fc0b53c06cfb.png


输⼊:matrix = [[1,2,3],[4,5,6],[7,8,9]] 输出:[1,2,3,6,9,8,7,4,5]


答案及解题思路见下方,欢迎讨论。


最后的话 :如果大家觉得这篇文章对你们有帮助的话希望你们能够点点关注,你们的关注是我继续写下去的动力,谢谢大家。


答案与思路:


螺旋方阵的输入: 输入方阵从最外层到内层可以看做大正方形套小正方形,即我们从最外层输入,通过四个for语句调换方 向输入,当外层输入完成后,进入内层( cnt -- )后再次进行输入直到最后


#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <memory.h>
int main() {
    int n, k, b;
    scanf("%d", &n);
    int i, j, c = 0, r = 0, num = 0, cnt = n / 2;
    int a[10][10];
    memset(a, 0, sizeof(a)); //初始化
    while (cnt--) { //控制循环输入次数
        for (i = r; i < n - c; i++) //→ 输入行,固定行移动列,数字依次增加,当移至第n列则进行下一步
            a[r][i] = ++num;
        r++;
        for (i = r; i < n - c; i++) //↓ 同理移动输入
            a[i][n - c - 1] = ++num;
        c++;
        for (i = c - 1; i < n - c; i++) //←
            a[n - r][n - i - 2] = ++num;
        for (i = r; i < n - r; i++) //↑
            a[n - 1 - i][c - 1] = ++num;
    }
    if (n % 2 != 0) //如果是奇数,填上正中间那个数
        a[n / 2][n / 2] = ++num;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            printf("%d ", a[i][j]);
        }
    }
    return 0;
}
目录
相关文章
|
7月前
|
存储 人工智能 程序员
一文彻底搞明白C语言的数组
本文详细介绍了C语言中的数组,包括定义、初始化(静态与动态)、存储方式、访问方法及常用操作,如遍历、修改元素和作为函数参数传递。数组是C语言中最基本的数据结构之一,掌握它对编程至关重要。下篇将介绍二维数组,敬请期待!
309 0
一文彻底搞明白C语言的数组
|
9月前
|
传感器 算法 安全
【C语言】两个数组比较详解
比较两个数组在C语言中有多种实现方法,选择合适的方法取决于具体的应用场景和性能要求。从逐元素比较到使用`memcmp`函数,再到指针优化,每种方法都有其优点和适用范围。在嵌入式系统中,考虑性能和资源限制尤为重要。通过合理选择和优化,可以有效提高程序的运行效率和可靠性。
657 6
|
10月前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
277 5
|
10月前
|
存储 程序员 编译器
C 语言数组与指针的深度剖析与应用
在C语言中,数组与指针是核心概念,二者既独立又紧密相连。数组是在连续内存中存储相同类型数据的结构,而指针则存储内存地址,二者结合可在数据处理、函数传参等方面发挥巨大作用。掌握它们的特性和关系,对于优化程序性能、灵活处理数据结构至关重要。
|
10月前
|
存储 NoSQL 编译器
C 语言中指针数组与数组指针的辨析与应用
在C语言中,指针数组和数组指针是两个容易混淆但用途不同的概念。指针数组是一个数组,其元素是指针类型;而数组指针是指向数组的指针。两者在声明、使用及内存布局上各有特点,正确理解它们有助于更高效地编程。
|
10月前
|
存储 C语言 计算机视觉
在C语言中指针数组和数组指针在动态内存分配中的应用
在C语言中,指针数组和数组指针均可用于动态内存分配。指针数组是数组的每个元素都是指针,可用于指向多个动态分配的内存块;数组指针则指向一个数组,可动态分配和管理大型数据结构。两者结合使用,灵活高效地管理内存。
|
10月前
|
存储 人工智能 算法
数据结构实验之C 语言的函数数组指针结构体知识
本实验旨在复习C语言中的函数、数组、指针、结构体与共用体等核心概念,并通过具体编程任务加深理解。任务包括输出100以内所有素数、逆序排列一维数组、查找二维数组中的鞍点、利用指针输出二维数组元素,以及使用结构体和共用体处理教师与学生信息。每个任务不仅强化了基本语法的应用,还涉及到了算法逻辑的设计与优化。实验结果显示,学生能够有效掌握并运用这些知识完成指定任务。
197 4
|
11月前
|
存储 编译器 C语言
【c语言】数组
本文介绍了数组的基本概念及一维和二维数组的创建、初始化、使用方法及其在内存中的存储形式。一维数组通过下标访问元素,支持初始化和动态输入输出。二维数组则通过行和列的下标访问元素,同样支持初始化和动态输入输出。此外,还简要介绍了C99标准中的变长数组,允许在运行时根据变量创建数组,但不能初始化。
187 6
|
11月前
|
存储 算法 C语言
C语言:什么是指针数组,它有什么用
指针数组是C语言中一种特殊的数据结构,每个元素都是一个指针。它用于存储多个内存地址,方便对多个变量或数组进行操作,常用于字符串处理、动态内存分配等场景。
|
11月前
|
存储 C语言
C语言:一维数组的不初始化、部分初始化、完全初始化的不同点
C语言中一维数组的初始化有三种情况:不初始化时,数组元素的值是随机的;部分初始化时,未指定的元素会被自动赋值为0;完全初始化时,所有元素都被赋予了初始值。
1177 2