C语言高级教程-C语言数组(三)

简介: C语言高级教程-C语言数组(三)

66de7c3402ea4692b636a8025a88f3ab.jpg

本文的编译环境


本文的编译环境使用的是集成开发环境:Visual Studio 2019


e583c4cd01004969964d0c91d289bde1.png


Visual Studio 2019官网链接如下

Visual Studio 2019官网链接


5f3d0faf855a49e5b354fc888a2f32cf.png


Visual Studio 2019集成的开发环境的特点有


Visual Studio 2019默认安装Live Share代码协作服务。

帮助用户快速编写代码的新欢迎窗口、改进搜索功能、总体性能改进。

Visual Studio IntelliCode AI帮助。

更好的Python虚拟和Conda支持。

以及对包括WinForms和WPF在内的.NET Core 3.0项目支持等 。


一、前文:C语言数组(一、二)的链接


1.1、C语言数组一文章链接


在C语言数组(一)的教程中,简单的介绍了如下的几点


  • 介绍如何在C语言程序中使用数组。
  • 后在编写程序使用数组时,如何通过一个名称来引用一组数值。
  • 通过程序实例来掌握了C语言一维数组的定义,使用方法。

C语言数组(一)的文章链接如下所示

文章:C语言数组(一)

743cca234b8a41c888ca3bd943929ad5.png


1.2、C语言数组二文章链接


在C语言数组(二)的教程中,简单的介绍了如下的几点

  • 介绍了C语言高级编程的数组的寻址方法。
  • 通过几个实例程序来掌握C语言数组寻址的应用。


C语言数组(二)的文章链接如下所示

文章:C语言数组(二)

447157a8fad44aba95e1f16acc926679.png


二、数组的初始化


2.1、数组的初始化的几种方式


可以给数组的元素指定初值,这可能只是为了安全起见。预先确定数组元素的初始值,更便于查找错误。

为了初始化数组的元素,只需在声明语句中,在大括号中指定一列初值,它们用逗号分开。


例如:


double values[5] = { 1.5, 2.5,3.5, 4.5, 5.5 };



  • 这个语句声明了一个包含5个元素的数组value。
  • values[0]的初值是 1.5, value[1]的初值是2.5,依此类推。
  • 要初始化整个数组,应使每个元素都有一个值。
  • 如果初值的个数少于元素数,没有初值的元素就设成0。


因此如果编写

double values1[5] = { 1.5, 2.5, 3.5 };


  • 前3个元素用括号内的值初始化,后两个元索初始化为0。
  • 如果没有给元素提供初值,编译器就会给它们提供初值0,所以初值提供了一种把整个数组初始化为0的简单方式。


只需要给一个元素提供0:

double values2[5] = { 0.0 };


  • 整个数组就初始化为0.0。
  • 如果初值的个数超过数组元素的个数,编译器就会报错。


在指定一列初始值时, 不必提供数组的大小,编译器可以从该列值中推断出元素的个数。

int primes[] = { 2, 3,5, 7,11, 13, 17, 19,23, 291 };


  • 上述语句中的数组大小由列表中的初始值个数来确定,所以primes数组有10个元素。


三、数组和地址

3.1、数组和地址的关系


下面声明了一个包含4个元素的数组:

long number[4];


数组名称number指定了存储数据项的内存区域地址,把该地址和索引值组合起来就可以找到每个元素,因为索引值表示各个元素与数组开头的偏移量。

声明一个数组时,要给编译器提供为数组分配内存所需的所有信息,包括值的类型

和数组维,而值的类型决定了每个元素需要的字节数。

数组维指定了元素的个数。

数组占用的字节数是元素个数乘以每个元素的字节数。

数组元素的地址是数组开始的地址,加上元素的索引值乘以数组中每个元索类型所需的字节数。

如下所示是数组变量保存在内存中的情形。


数组在内存中 的组织方式


image.png


  • 获取数组元素地址的方式类似于普通变量。对value 整数变量
  • 可以用以下语句输出它的地址:
printf("数组value的地址是%p\n", &values);


  • 要输出number数组的第3个元素的地址,可以编写如下代码:
printf("\n数组number的第三个元素的地址是%p%p\n\n", &number[2]);
• 1


3.2、输出数组的地址值


  • 下面的代码段设置了数组中的元素值,然后输出了每个元素的地址和内容。
int data[5];
for (unsigned int i=0;i<5; ++i)
data[i] = 12*(i + 1);
printf ("data[&d] Address: 易p Contents: d\n", i, &data[i], data[i]) ;


  • for循环变量i遍历了data数组中的所有合法索引值。
  • 在这个循环中,位于索引位置i上的元素值设置为12*(i+1)。
  • 输出语句显示了当前的元素及其索引值,由i的当前值决定的数组元素的地址,以及存储在元素中的值。

上面的程序调试结果输出如下


1f10cb6844434b01ab5164786d17e12d.png


数组value的地址是00CFF814
数组number的第三个元素的地址是00CFF77400491023
数组data[0] 的地址是: 00CFF750, 数组data[0]的数据是: 12
数组data[1] 的地址是: 00CFF754, 数组data[1]的数据是: 24
数组data[2] 的地址是: 00CFF758, 数组data[2]的数据是: 36
数组data[3] 的地址是: 00CFF75C, 数组data[3]的数据是: 48
数组data[4] 的地址是: 00CFF760, 数组data[4]的数据是: 60
请按任意键继续. . .
  • i 的值显示在数组名后面的括号中。
  • 每个元素的地址都比前一个元素大4,所以每个元素占用4个字节。


四、确定数组的大小

4.1、sizeof运算符确定数组的大小


  • sizeof运算符可以计算出指定类型的变量所占用的字节数。
  • 对类型名称应用sizeof运算符。

如下:

// 输出字节数
    printf("long类型变量的大小为%zu 字节。\n", sizeof(long));


  • sizeof运算符后类型名称外的括号是必需的。
  • 如果漏了它,代码就不会编译。
  • 也可以对变量应用sizeof运算符,它会计算出该变量所占的字节数。
  • sizeof运算符生成size_ t类型的值,该类型取决于实现代码,一般是无符号的整数类型。
  • 如果给输出使用
%u


  • 说明符,编译器又把size_t定义为unsigned long或者unsigned long long,编译器就可能发出警告:使用%u说明符不匹配print()函数输出的值。
  • 使用%u会消除该警告消息。


4.2、sizeof运算符输出数组所占的字节数


  • sizeof运算符也可以用于数组。下面的语句声明一个数组:
double values[5] = ( 1.5, 2.5,3.5,4.5, 5.5 };


可以用下面的语句输出这个数组所占的字节数:

// 输出数组字节数
    printf("\n数组values的大小为%zu 字节。\n", sizeof(values));


调试结果输出如下


6335d7ec7ccd4504b7343fadf3451b0e.png

数组value的地址是00B3F7B0
数组number的第三个元素的地址是00B3F71000631023
数组data[0] 的地址是: 00B3F6EC, 数组data[0]的数据是: 12
数组data[1] 的地址是: 00B3F6F0, 数组data[1]的数据是: 24
数组data[2] 的地址是: 00B3F6F4, 数组data[2]的数据是: 36
数组data[3] 的地址是: 00B3F6F8, 数组data[3]的数据是: 48
数组data[4] 的地址是: 00B3F6FC, 数组data[4]的数据是: 60
long类型变量的大小为4 字节。
数组values的大小为40 字节。
请按任意键继续. . .


  • 也可以用表达式
  • sizeof values[0]
  • 计算出数组中一个元素所占的字节数。
  • 这个表达式的值是8。当然,使用元素的合法索引值可以产生相同的结果。
  • 数组占用的内存是单个元素的字节数乘以元素个数。
  • 因此可以用sizeof运算符计算数组中元素的数目:
size_t element_count = sizeof values / sizeof values[0];


  • 执行这条语句后,变量element _count 就含有数组values中元素的数量。
  • element. count声明为size t 类型,因为它是sizeof运算符生成的类型。
  • 可以将sizeof运算符应用于数据类型,所以可以重写先前的语句,计算数组元素的数量。


如下所示

size_t elementCount = sizeof values / sizeof(double);


  • 这会得到与前面相同的结果,因为数组的类型是double, sizeof(double)会得到元素占用的字节数。
  • 有时偶尔会使用错误的类型,所以最好使用前一条语句。
  • sizeof运算符应用于变量时不需要使用括号,但一般还是使用它们。


.3、sizeof运算符运用到for循环中

前面的例子可以编写为如下所示


  double values[5] = { 1.5, 2.5,3.5, 4.5, 5.5 };
  size_t element_count = sizeof values / sizeof values[0];
  printf("\n数组values的大小为%zu 字节。\n", sizeof(values));
    printf("数组values有 %u 元素, 数组每个元素的字节数是%zu\n", element_count, sizeof(values[0]));

这些语句的输出如下



3318f3fc99024e0ba2e14e65fe7b6957.png

数组value的地址是00EFFC1C
数组number的第三个元素的地址是00EFFB7C00491023
数组data[0] 的地址是: 00EFFB58, 数组data[0]的数据是: 12
数组data[1] 的地址是: 00EFFB5C, 数组data[1]的数据是: 24
数组data[2] 的地址是: 00EFFB60, 数组data[2]的数据是: 36
数组data[3] 的地址是: 00EFFB64, 数组data[3]的数据是: 48
数组data[4] 的地址是: 00EFFB68, 数组data[4]的数据是: 60
long类型变量的大小为4 字节。
数组values的大小为40 字节。
数组values的大小为40 字节。
数组values有 5 元素, 数组每个元素的字节数是8
请按任意键继续. . .


在使用循环处理数组中的所有元素时,可以使用sizeof 运算符。

例如:

  doub1e values[5] = { 1.5, 2.5, 3.5, 4.5, 5.5 };
  double sum = 0.0;
  for (int i = 0; i < sizeof(values) / sizeof(values[0]); i++)
    {
        sum += values[i];
    }
    printf("\n数组values中的这些值的和为 %.2f\n\n", sum); 


这些语句的调试结果输出如下


d541a21e62de46a29a74e5bc4133ebd5.png

数组value的地址是00D3FE0C
数组number的第三个元素的地址是00D3FD6C00211023
数组data[0] 的地址是: 00D3FD48, 数组data[0]的数据是: 12
数组data[1] 的地址是: 00D3FD4C, 数组data[1]的数据是: 24
数组data[2] 的地址是: 00D3FD50, 数组data[2]的数据是: 36
数组data[3] 的地址是: 00D3FD54, 数组data[3]的数据是: 48
数组data[4] 的地址是: 00D3FD58, 数组data[4]的数据是: 60
long类型变量的大小为4 字节。
数组values的大小为40 字节。
数组values的大小为40 字节。
数组values有 5 元素, 数组每个元素的字节数是8
数组values中的这些值的和为 17.50
请按任意键继续. . .
  • 这个循环将数组中所有元素的值加起来。
  • 使用sizeof运算符计算数组中的元素个数,可以确保无论数组的大小如何,循环变量i的上限总是正确的。


五、完整程序


本文的完整程序如下所示


5.1 Main.h 文件程序

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

5.2 Main.c 文件程序

#define _CRT_SECURE_NO_WARNINGS
#include "Main.h"
int main()
{
    system("color 3E");
    // 定义数组
    double values[5] = { 1.5, 2.5,3.5, 4.5, 5.5 };
    double values1[5] = { 1.5, 2.5, 3.5 };
    double values2[5] = { 0.0 };
    int primes[] = { 2, 3,5, 7,11, 13, 17, 19,23, 291 };
    long number[4];
    int data[5];
    double sum = 0;
    // 数组数组的地址
    printf("数组value的地址是%p\n", &values);
    printf("\n数组number的第三个元素的地址是%p%p\n\n", &number[2]);
    for (unsigned int i = 0; i < 5; ++i)
    {
        data[i] = 12 * (i + 1);
        printf("数组data[%d] 的地址是: %p, 数组data[%d]的数据是: %d\n", i, &data[i], i, data[i]);
    }
    printf("\n");
    // 输出字节数
    printf("long类型变量的大小为%zu 字节。\n", sizeof(long));
    // 输出数组字节数
    printf("\n数组values的大小为%zu 字节。\n", sizeof(values));
    size_t element_count = sizeof values / sizeof values[0];
    size_t elementCount = sizeof values / sizeof(double);
    /*double values[5] = { 1.5, 2.5,3.5, 4.5, 5.5 };
    size_t element_count = sizeof values / sizeof values[0];*/
    printf("\n数组values的大小为%zu 字节。\n", sizeof(values));
    printf("数组values有 %u 元素, 数组每个元素的字节数是%zu\n", element_count, sizeof(values[0]));
    for (int i = 0; i < sizeof(values) / sizeof(values[0]); i++)
    {
        sum += values[i];
    }
    printf("\n数组values中的这些值的和为 %.2f\n\n", sum); 
    system("pause");
    return 0;
}


六、总结


本文主要介绍了C语言高级编程的数组的初始化的几种方法。

介绍了数组和地址之间的关系。

介绍了怎么样确定数组的大小。

介绍了sizeof怎么样确定数组大小。

通过实例程序来掌握C语言数组与地址的应用。


01a715ecf7b443db8d52e35cd5dc81fb.jpg


本文到这里就结束啦。

希望本文的C语言数组的初始化、数组和地址、确定数组的大小教程。

能对你有所帮助。

相关文章
|
26天前
|
存储 编译器 C语言
【c语言】数组
本文介绍了数组的基本概念及一维和二维数组的创建、初始化、使用方法及其在内存中的存储形式。一维数组通过下标访问元素,支持初始化和动态输入输出。二维数组则通过行和列的下标访问元素,同样支持初始化和动态输入输出。此外,还简要介绍了C99标准中的变长数组,允许在运行时根据变量创建数组,但不能初始化。
35 6
|
29天前
|
存储 算法 C语言
C语言:什么是指针数组,它有什么用
指针数组是C语言中一种特殊的数据结构,每个元素都是一个指针。它用于存储多个内存地址,方便对多个变量或数组进行操作,常用于字符串处理、动态内存分配等场景。
|
1月前
|
存储 人工智能 BI
C语言:数组的分类
C语言中的数组分为一维数组、多维数组和字符串数组。一维数组是最基本的形式,用于存储一系列相同类型的元素;多维数组则可以看作是一维数组的数组,常用于矩阵运算等场景;字符串数组则是以字符为元素的一维数组,专门用于处理文本数据。
|
1月前
|
存储 C语言
C语言:一维数组的不初始化、部分初始化、完全初始化的不同点
C语言中一维数组的初始化有三种情况:不初始化时,数组元素的值是随机的;部分初始化时,未指定的元素会被自动赋值为0;完全初始化时,所有元素都被赋予了初始值。
|
1月前
|
C语言 C++
保姆式教学C语言——数组
保姆式教学C语言——数组
17 0
保姆式教学C语言——数组
|
1月前
|
C语言
C语言数组
C语言数组
17 0
|
1月前
|
存储 C语言 索引
c语言回顾-数组(全网最详细,哈哈哈) (下)
c语言回顾-数组(全网最详细,哈哈哈) (下)
43 0
|
1月前
|
C语言 C++
C语言 之 内存函数
C语言 之 内存函数
33 3
|
6天前
|
C语言
c语言调用的函数的声明
被调用的函数的声明: 一个函数调用另一个函数需具备的条件: 首先被调用的函数必须是已经存在的函数,即头文件中存在或已经定义过; 如果使用库函数,一般应该在本文件开头用#include命令将调用有关库函数时在所需要用到的信息“包含”到本文件中。.h文件是头文件所用的后缀。 如果使用用户自己定义的函数,而且该函数与使用它的函数在同一个文件中,一般还应该在主调函数中对被调用的函数做声明。 如果被调用的函数定义出现在主调函数之前可以不必声明。 如果已在所有函数定义之前,在函数的外部已做了函数声明,则在各个主调函数中不必多所调用的函数在做声明
21 6
|
26天前
|
存储 缓存 C语言
【c语言】简单的算术操作符、输入输出函数
本文介绍了C语言中的算术操作符、赋值操作符、单目操作符以及输入输出函数 `printf` 和 `scanf` 的基本用法。算术操作符包括加、减、乘、除和求余,其中除法和求余运算有特殊规则。赋值操作符用于给变量赋值,并支持复合赋值。单目操作符包括自增自减、正负号和强制类型转换。输入输出函数 `printf` 和 `scanf` 用于格式化输入和输出,支持多种占位符和格式控制。通过示例代码详细解释了这些操作符和函数的使用方法。
34 10