IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C语言初阶2:数组 -> 正文阅读

[C++知识库]C语言初阶2:数组

1、初始化

1.1 整体初始化

(1)代码1

#include <stdio.h>
void main(){
	int arr[12];
	for(int i=0;i<12;++i){
	    printf("%d ",arr[i]);
	}
}

(2)代码2

#include <stdio.h>
void main(){
    int arr[12] = {0};
    for(int i=0;i<12;++i){
        printf("%d ",arr[i]);
    }
}

(3)代码3

#include <stdio.h>
void main(){
	int arr[12] = {2};
	for(int i=0;i<12;++i){
	    printf("%d ",arr[i]);
	}
}

(4)输出结果分析

1)代码1:输出全为不规则的数字
2)代码2:输出全为0
3)代码3:输出一个2,其他全为0

(5)结论

1)数组未初始化,数组里面的值都是随机值。
2)数组初始化为{0},数组里面的值都是03)数组初始化为{非零值},数组里面第一个值是非零值,其他的值都是0

1.2 部分初始化

#include <stdio.h>
void main(){
    int arr[12] = {[2]=2,[5]=5};
    for(int i=0;i<12;++i){
        printf("%d ",arr[i]);
    }
}

指定下标的值被赋值,其他为0

1.3 大小

#include <stdio.h>
void main(){
    char carr[12];
    int iarr[12];
    double farr[12];
    printf("carr = %d\n",sizeof(carr));
    printf("iarr = %d\n",sizeof(iarr));
    printf("farr = %d\n",sizeof(farr));
}

输出结果为:
在这里插入图片描述
sizeof给出整个数组所占据的内容的大小。数组大小=元素大小*数组个数。

问题9:已知数组arr,如何求出数组元素个数?
sizeof(arr)/数组类型大小
char =1
int=4
float=8

1.4 赋值

int days[]={31,28,31,30,31,30,31,31,30,31,30,31};
int arr = days;

这个时候的赋值是错误的,因为int只是在int一个类型,这个时候days代表的是数组days[]的首个元素或者首元素的地址

2、数组与指针

2.1 数组名是地址

数组名是数组第一个元素的地址

#include <stdio.h>
void main(){
    int arr[] = {1,2,3,4,5,6,7,8};
    printf("&arr=%p\n",&arr);
    printf("arr=%p\n",arr);
    printf("&arr[0]=%p\n",&arr[0]);
}

输出为:

&arr=000000000061FE00
arr=000000000061FE00
&arr[0]=000000000061FE00

数组下标实现的操作指针也可以实现。数组名+下标表示下标i元素的地址
在这里插入图片描述
所以,遍历数组可以是:

#include <stdio.h>
void main(){
    int arr[] = {1,2,3,4,5,6,7,8};
    for(int i=0;i<8;++i){
        printf("%d\n",*(arr+i)); 
    }
}

数组名是不可以改变的!
i

nt arr1[] = {1,2,3,4,5,6,7,8};
int arr2[] = {1,2,3,4,5,6,7,8};
arr2 = arr1;//行不通的赋值方法

数组下标比较易于理解,数组指针更灵活更高效。
要点:

1)数组名是数组第一个元素的地址。
2)数组名+下标表示下标i元素的地址。
3)数组名是不可改变的。

2.2 数组名放入指针

地址存储在指针中。可以用指针操作地址。

#include <stdio.h>
void main(){
    int arr[] = {1,2,3,4,5,6,7,8};
    int* p = arr;
    for(int i=0;i<8;++i){
        printf("%d\n",*(p+i)); 
    }
}

3、函数与数组

3.1 传递数组给函数

数组作为函数参数时,通常必须再用一个参数传入数组大小。

返回值类型 函数名(类型 参数名[],int size){

}

或者

返回值类型 函数名(类型* 参数名,int size){

}

3.1.1 实践1

#include <stdio.h>

void PrintArr1(int arr[],int n){
    for(int i=0;i<n;++i){
        printf("%d ",arr[i]);
    }
    printf("\n");
}
void PrintArr2(int* arr,int n){
    for(int i=0;i<n;++i){
        printf("%d ",arr[i]);
    }
    printf("\n");
}
int main(){
    int arr[] = {1,2,3,4,5,6,7,8,9};
    PrintArr1(arr,9);
    PrintArr1(arr,3);
    PrintArr1(arr+6,3);
    PrintArr1(arr+3,3);
}

输出为:
1 2 3 4 5 6 7 8 9
1 2 3
7 8 9
4 5 6

3.1.2 实践2

#include <stdio.h>

void Test1(int a[]){
    printf("sizeof(a):%d\n",sizeof(a));
    printf("a:%p\t&a:%p\n",a,&a);
}
void Test2(int* p){
    printf("sizeof(p):%d\n",sizeof(p));
    printf("p:%p\t&p:%p\n",p,&p);
}
int main(){
    int arr[10];
    printf("sizeof(arr):%d\n",sizeof(arr));
    printf("arr:%p\t&arr:%p\n",arr,&arr);
    Test1(arr);
    Test2(arr);
}

输出为:

sizeof(arr):40
arr:000000000061FDF0    &arr:000000000061FDF0
sizeof(a):8
a:000000000061FDF0      &a:000000000061FDD0
sizeof(p):8
p:000000000061FDF0      &p:000000000061FDD0

3.1.3 练习

(1)两个有序数组的归并

输入一个整数n(n <= 10000)和n个整数a[i],保证这n个整数已按照从小到大进行排序。然后输入一个整数m(m <= 10000),和m个整数b[j],保证这m个整数已按照从小到大进行排序。
将两组数归并后输出。

代码:

#include <stdio.h>

void GetArry(int arry[],int n){
    for(int i=0;i<n;i++){
        scanf("%d",&arry[i]);
    }
}
void PrintArry(int arry[],int size){
    for(int i=0;i<size;i++){
        printf("%d\n",arry[i]);
    }
    printf("\n");
}

int main(){
    int n,m;   
    scanf("%d",&n);
    int a[n];
    GetArry(a,n);
    scanf("%d",&m);
    int b[m];
    GetArry(b,m);
    int c[m+n];

    int lengtha=sizeof(a)/sizeof(int);
    int lengthb=sizeof(b)/sizeof(int);
    int i=0,j=0,k=0;
    while (i<lengtha && j<lengthb)
    {
        if(a[i]<=b[j]){
            c[k++]=a[i++];
        }else{
            c[k++]=b[j++];
        }
    }
    while(i<lengtha){
        c[k++]=a[i++];
    }
    while (j<lengthb)
    {
        c[k++]=b[j++];
    }
    PrintArry(c,m+n);
}

3.2 从函数返回数组

C 语言不允许返回一个完整的数组作为函数的参数。通过指定不带索引的数组名来返回一个指向数组的指针。

类型* 函数名() {
   return 数组名;
}

3.2.1 练习

(1)给定数组随机填充指定范围的数据。使用stdlib.h中的srand(time(NULL))和rand()。

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

void PrintArry(int arry[],int n){
    for(int i=0;i<n;i++){
        printf("%d ",arry[i]);
    }
    printf("\n");
}

void main(){
    int n;
    scanf("%d",&n);
    int a[n];
    srand((int)(time(NULL)));
    for(int i=0;i<n;i++){
        
        a[i]=rand()%100;
    }
    PrintArry(a,n);   
}

(2)将一维数组的查找FindArr()、替换Replace()封装成函数。

#include <stdio.h>
#include <stdbool.h>

//打印函数
void PrintArry(int arry[],int n){
    for(int i=0;i<n;i++){
        printf("%d ",arry[i]);
    }
    printf("\n");
}

//查找函数
int FindArry(int arry[],int n,int num){
    for(int i =0;i<n;i++){
        if(arry[i]==num){
            return i;
        }
    }
    return -1;
}

//替换函数
void ReplaceNum(int arry[],int n,int num,int repnum){
    int index = FindArry(arry,n,num);
    if(index!=-1){
        arry[index]=repnum;
    }
}

void main(){
    int n;
    scanf("%d",&n);
    int a[n];
    for(int i=0;i<n;i++){
        scanf("%d",&a[i]);
    }
    PrintArry(a,n);
    int num;
    printf("请输入要查询的数字:");
    scanf("%d",&num);
    int index=FindArry(a,n,num);
    if(index!=-1){
        printf("Found %d:[%d]\n",num,index);
        int repnum;
        printf("请输入替换的数字:");
        scanf("%d",&repnum);
        ReplaceNum(a,n,num,repnum);
        PrintArry(a,n);
    }else{
        printf("Not Found %d\n",num);
    }
}

3.2.2 重点

int arr[] = {1,2,3,4,5,6};
// sizeof(数组名)
printf("sizeof(arr) = %ld\n",sizeof(arr));
// 数组名的值
printf("arr=%p\n&arr[0]=%p\n",arr,&arr[0]);

输出为:

sizeof(arr) = 24
arr=000000000061FE00
&arr[0]=000000000061FE00

数组名是地址,是常量。

1、可以使用指针操作:解引用
2、数组作为函数参数和返回值时,传指针/地址。

数组下标与数组长度的关系

1)arr长度为n,最后一个元素的下标为n-12)下标为i是第i+1个元素,前面有i个元素(不包含i),后面有n-(i+1)个元素(不包含i)3)下标i和j之间有j-i个元素(包含i,不包含j)

数组地址与数组名的关系

1)数组arr的首地址为arr,下标为i的地址为arr+i。
2)令p=arr+i,那么下标对应为p-arr。
3)p前面有p-arr个元素(不包含p),后面有n-(p-arr+1)个元素(不包含p)

4、多维数组

4.1 声明

4.1.1 语法

类型 数组名[元素个数1][元素个数2]...[元素个数N];

多维数组最常用形式是二维数组。二维数组相当于一个行列组成的表。

类型 二维数组名[行数][列数];

例如下面是一个4行3列元素类型为int的表。

int days[4][3];

4.2 初始化二维数组

多维数组可以通过在括号内为每行指定值来进行初始化。

int days[4][3]={
    {31,28,31},
    {30,31,30},
    {31,31,30},
    {31,30,31}
};

4.3 访问二维数组元素

二维数组中的元素是通过使用下标(即数组的行索引和列索引)来访问的。
在这里插入图片描述

// 获取一月份的天数
int n = days[0][0];
// 修改二月份的天数
days[0][1] = 29;
// 打印一月份天数
printf("%d",days[0][0]);

4.4 二维数组元素遍历

通常使用嵌套循环来处理二维数组。

for (int i = 0; i < 4; i++ ) {
    for (int j = 0; j < 3; j++ ) {
       printf("a[%d][%d] = %d\n",i,j,a[i][j]);
    }
}

4.5 二维数组输入

int n,m;
scanf("%d%d",&n,&m);
int arr[n][m];
for (int i=0;i<n;++i){
  for (int j=0;j<m;++j){
      scanf("%d",&arr[i][j]);
  }
}

4.5.1 练习

(1)输入m个学生的n门课程成绩,输出各门课程成绩以及总成绩和平均值。

#include <stdio.h>

void main(){
    int n,m;
    printf("请输入学生数(n)和科目数(m):\n");
    scanf("%d%d",&n,&m);
    int grades[n][m];
    for(int i=0;i<n;i++){
        for (int j = 0; j < m; j++)
        {
            scanf("%d",&grades[i][j]);
        }
    }
    for (int i = 0; i < n; i++)
    {
        int sum=0;
        for (int j = 0; j < m; j++)
        {
            printf("%d\t",grades[i][j]);
            sum+=grades[i][j];
        }
        printf("%d\t%.2f\n",sum,(float)sum/m);       
    } 
}

4.6 简化

初始化二维数组可以有如下简化写法:

(1)省略内部嵌套括号。

int days[4][3]={31,28,31,30,31,30,31,31,30,31,30,31};

(2)省略第一维的大小,但是不能省略第二维的大小

int days[][3]={31,28,31,30,31,30,31,31,30,31,30,31};

4.7 二维数组作为函数的参数

void PrintMatrix(int m[4][3],int r,int c)
for (int i = 0; i < r; i++ ) {
    for (int j = 0; j < c; j++ ) {
       printf("%d\n",m[i][j]);
    }
}

4.8 多维数组

大于二维的数组的用法与二维数组一样,只是使用比较少。

int days[][4][3]={
    {31,28,31,30,31,30,31,31,30,31,30,31}, // 平年
    {31,29,31,30,31,30,31,31,30,31,30,31}  // 闰年
};

printf("平年二月天数为%d\n",days[0][0][1]);// 平年第一季度第二个月
printf("闰年二月天数为%d\n",days[1][0][1]);// 闰年第一季度第二个月 

多维数组初始化只能第一个维度可以省略。

5、const数组

5.1 const数组是什么?

const int arr[]={1,2,3,4,5,};

数组变量已经是const指针,表示数组中的每一个元素都是const int,即每个元素不能通过arr改变。
例如:

const int arr[]={1,2,3,4,5,};
arr[0] = 0;

这个时候编译执行就会出错

6、变量指针 vs 数组指针

变量指针:指向单个变量的指针。
数组指针:指向数组的指针。

#include <stdio.h>

int main () {
    int n = 10;
    int *p;
    p = &n; // p指针指向变量
    printf("*p = %d\n",*p);
    
    int arr[] = {1,2,3,4,5,};
    p = arr;// p指针指向数组
    printf("*p = %d\n",*p);
    printf("*(p+1) = %d\n",*(p+1));
    printf("*(p+2) = %d\n",*(p+2));
    printf("*(p+3) = %d\n",*(p+3));
    printf("*(p+4) = %d\n",*(p+4));
    
    return 0;
}

指针既可以指向一个基本类型变量又可以指向一个数组。所以在使用时要注意分辨。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章           查看所有文章
加:2021-10-30 12:23:34  更:2021-10-30 12:25:44 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 5:53:37-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码