数组_C语言

作者: MathCat | 来源:发表于2016-09-03 13:39 被阅读0次

定义

数组就是相同数据类型构成的一组数

数组名

  • 数组名的值是一个指针常量(你不能修改常量的值),它是数组第一个元素的地址,他的类型取决于数组元素的类型
  • 数组和指针是不一样的,数组具有确定数量的元素,而指针只是个标量值
  • 指针常量所指向的是内存中数组的起始位置,如果修改这个指针常量,唯一可行的方法就是把整个数组移动到内存的其他位置

只有在两种场合下,数组名并不用指针常量来表示

  1. 当数组名作为sizeof操作符,sizeof返回整个数组的长度,而不是指向数组的指针的长度
  2. 单目操作符&的操作数时,取一个数组名的地址所产生的是一个指向数组的指针,而不是指向某个指针常量值得指针

这两者是等价的

int a[10];

int *c;
c = &a[0];
c = a;

初始化

类型标识符 + 数组名 + 数组元素的个数(常量表达式) + 初始值

int arr[5] = {0};
  • excess element 超过 数组越界
    数组元素不要超过给定的,数组越界有可能导致程序崩溃
    中括号中数组的元素的个数
  • 不能放变量
int arr6[4] = {1,2,3,4,5};
int i = 10;

int arr1[i] = {0};

int arr1[8 + 2] = {0};

int arr2[] = {1,2,3};// 不建议

float arr3[3] = {1.0,2.0,3.0};

double arr4[3] = {2.0,3.0,4.023123};

long arr5[4] = {5345,64563,234};

指针 和 下标

下标

下标和数组名一起使用,用于标识该集合中某个特定的值

int b[10];
*(b+3);

b的值是一个指向整型的指针,*(b+3)所指向的是数组的第1个元素向后移3个整数长度的位置,然后间接访问这个新的位置

除了优先级之外,下标引用和间接访问完全相同

array[subscript];
*(array+(subscript));

关于下标和指针的理解

int array[10];
int *ap = array +2;
指针 转换 下标
ap array + 2 &array[2]
*ap *(array + 2) array[2]
ap[0] *(ap+(0)) = array + 2 &array[2]
ap+6 array + 2 + 6 = array + 8 &array[8]
*ap+6 *(array + 2) + 6 array[2]+6
*(ap+6) *(array 2 + 6) array[8]
ap[6] *(ap+(6)) &array[8]
&ap ap指针所在的地址
ap[-1] *(array+(-1)) array[1]

2[array]相当于*(2+(array))也就是说*(array+2)

  • 有些编译器会有下标检查,但这是一个不小的负担,不过对于如今的电脑而言,并不是个大的问题
  • 指针有时候会比下标更有效率,但不应因为效率而影响程序的可读性

一般有数组的地方就有循环

遍历一个数组 数组下标,从0开始到 数组元素个数-1 为止

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

数组 和 指针

  • 声明一个数组时,编译器将根据声明所指定的元素数量为数组元素保留内存空间,然后在创建数组名,它的值是一个常量,指向这段空间的起始位置.
  • 声明一个指针变量时,编译器只为指针变量保存内存空间,如果它是一个自动变量,它甚至根本不会被初始化
int a[5];
int *b;

上述声明后

  • 表达式*a是完全合法的,但表达式*b是非法的
  • *b将访问内存中某个不确定的位置,或者导致程序终止
  • b++能通过编译,但a++却不能,因为a的值是一个常量

作为函数参数的数组名

当数组名作为参数传递给函数时是指向数组第一个元素指针的拷贝,函数如果执行了下标引用,实际上是对这个指针执行间接访问操作,函数可以访问和修改调用程序的数组元素

以下两个声明只是在当前这个上下文环境中相等

int fun(char *string);
int fun(char string[]);

字符数组 和 字符串

字符数组

char arr[4] = {'a','n','s','d'};
char arr[4] = "ansd";

以下声明,尽管第二个声明看像去是一个字符串常量,实际上并不是

char message[] = "Hello";
char *message2 = "Hello";

以上声明

  • 前者初始化一个字符数组的元素
  • 后者是一个真正的字符串常量,这个指针变量被初始化为指向这个字符串常量的存储位置

输出方法

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

多维数组

初始化

// 方法一
int matrix[2][3] = {100,101,102,110,111,112};
// 方法二
matric[0][2] = 102;
// 方法三
int matix2[3][5]={
    {00,01,02,03,04},
    {10,11,12,13,14},
    {20,21,22,23,24}
}

存储顺序

int a[12];
int b[3][4];
int c[2][2][3];
数值 int a[12]; int b[3][4]; int c[2][2][3];
0 a[0] b[0][0] c[0][0][0]
1 a[1] b[0][1] c[0][0][1]
2 a[2] b[0][2] c[0][0][2]
3 a[3] b[0][3] c[0][1][0]
4 a[4] b[1][0] c[0][1][1]
5 a[5] b[1][1] c[0][1][2]
6 a[6] b[1][2] c[1][0][0]
7 a[7] b[1][3] c[1][0][1]
8 a[8] b[2][0] c[1][0][2]
9 a[9] b[2][1] c[1][1][0]
10 a[10] b[2][2] c[1][1][1]
11 a[11] b[2][3] c[1][1][2]
// 给数组a赋值
    int *d = a;
    for (int i = 0; i < 12; i++)
    {
        *d = i;
        d++;
    }
// 给数组b赋值
    d = &b[0][0];
    for (int i = 0; i < 12; i++)
    {
        *d = i;
        d++;
    }
// 给数组c赋值
    d = **C;
    for (int i = 0; i < 12; i++)
    {
        *d = i;
        d++;
    }
    // 打印数组a
    for (int i = 0; i < 12; i++)
    {
        cout << "a"<<i<<"="<<a[i] << endl;
        // printf("a[%d] = %d \n", i,a[i]);
    }
    // 打印数组b
    for (int i = 0; i < 3; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            cout << "b" << i << j <<"=" << b[i][j] << endl;
        }   
    }
    // 打印数组c
    for (int i = 0; i < 2; i++)
    {
        for (int j = 0; j < 2; j++)
        {
            for (int k = 0; k < 3; k++)
            {
                cout << "c" <<i<<j<<k<<"=" <<c[i][j][k] << endl;
            }
        }
    }

数组名

  • 一维数组名得值是一个指针常量,类型:指向元素类型的指针,它指向数组的1个元素
  • 二维数组名的值是一个指向一个包含x个某类型元素的数组的指针
int matrix[2][3];
  • matrix; 类型:指向包含3个整形元素的数组的指针
  • *matrix; 类型:指向整形的指针

下标

array[s2][s1];
*(*(array+(s1))+(s2));

注意:

array[3,4];

相当于

array[4];

逗号操作符首先对第1个表达式求值,但随即丢弃这个值,最后的结果是第2个表达式的值

指向数组的指针

对于一维数组,以下声明是合法的

int vector[10],*vp = vector;

但对于多维数组,以下声明则是非法的

int matrix[3][10],*mp = matrix;

因为matrix并不是一个指向整形的指针,而是一个指向整形数组的指针,其指针声明如下

int (*)p[10];

下标的引用的优先级高于间接访问,但由于括号的存在,首先执行的还是间接访问,接下来执行的是下标引用,所以p指向的是某种类型的数组,对该数组进行下标引用操作得到的是一个整型值,所以p是一个指向整型数组的指针

int (*p)[10] = matrix;

它使p指向matrix的第一行,p是一个指向拥有10个整形元素的数组指针
如果需要一个指针逐个访问整型元素可以进行如下声明

int *pi = &matrix[0][0];
int *pi = matrix[0];

作为参数的多维数组

其实际传递的是指向数组第一个元素的指针,多维数组的每个元素本身是另外一个数组,编译器需要知道它的维数,以便为函数形参的下标表达式求值

int matrix[3][10];
fun(matrix);

参数matrix的类型是指向包含10个整形元素的数组的指针

fun的函数原型如下

void fun(int (*mat)[10]);
void fun(int mat[][10]);

数组长度自动计算

对于多维数组,只有第一维才能根据初始化列表缺省地提供,其他几个维度必须显式地写出

指针数组

int *api[10];
  • 下标引用高于间接访问,所以在这个表达式中,首先执行下标引用,因此api是某类型的数组,其元素个数为10
  • 随后进行间接访问操作,得到一个整形,所以其元素类型为指向整形的指针

例:

以下为一个指针数组

char const keyword[]={
    "do",
    "for",
    "if",
    "register",
    "return";
    "switch"
    "while"
};
#define N_KEYWORD (sizeof(keyword)/sizeof(keyword[0]))

以下则为一个矩阵

char const keyword[][9]={
    "do",
    "for",
    "if",
    "register",
    "return";
    "switch"
    "while"
};

sizeof用于对数组中的元素进行自动计数

  • 通过sizeof来得到数组中元素的个数
  • sizeof(keyword)的结果为整个数组所占用的字节数
  • sizeof(keyword[0])为数组每个元素所占用的字节数
  • 这两个数相除为整个数组的个数

sizeof是字符的大小

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

sizeof(a) / sizeof(int) 数据大小 / 数据类型大小 = 多少个

数组:排序 冒泡排序

冒泡排序是一个双层的for循环 ,外层循环控制的是比较的趟数,内层循环控制的是每次比较的次数

   int arr6[5] = {6,5,4,3,1};
   for(int i = 0; i < 5 - 1; i++) {
       for(intj = 0; j < 5 - i - 1; j++) {
           if(arr6[j] > arr6[j+1]) {
                arr6[j] = arr6[j] ^ arr6[j+1];
                arr6[j+1] = arr6[j] ^ arr6[j+1];
                arr6[j] = arr6[j] ^ arr6[j+1];
            }
        }
    }
   for(int i = 0; i < 5; i++) {
       printf("arry5[%d] is %d\n",i,arr6[i]);
    }

相关文章

  • C语言数组的升维与降维之说

    C语言数组的升维与降维之说 C语言数组的升维 C语言数组的降维

  • 指针数组和数组指针

    指针数组|存储指针的数组 在C语言和C++语言中,数组元素全为指针的数组称为指针数组。 例如:int *p[10]...

  • C语言中的指针与数组

    C语言中的指针与数组 @(C语言)[排序算法, 快速排序, C实现] 引言 相信指针与数组是不少同学在初学C语言时...

  • 0基础学习C语言第七章:数组(2)

    C语言 多维数组 C 语言支持多维数组。多维数组声明的一般形式如下: type name[size1][size2...

  • iOS开发 -- C语言基础6(数组)

    iOS开发 -- C语言基础6(数组) C语言数组 一、数组的概念 用来存储一组数据的构造数据类型 特点:只能存放...

  • 2020-11-17--02--windows 数据类型

    windows系统是c语言开发的 字符数组,是c语言,重新定义的 Lstrlen-------C语言函数=====...

  • 数据结构--单向链表

    C语言中,我们在使用数组时,会需要对数组进行插入和删除的操作,这时就需要移动大量的数组元素,但在C语言中,数组属于...

  • C语言数组

    #include int main (void){ int a [20];//称a为20个元素的数组,每个...

  • C语言----数组

    C 语言支持数组数据结构,它可以存储一个固定大小的相同类型元素的顺序集合。数组是用来存储一系列数据,但它往往被认为...

  • C语言数组

    说真的感受到c语言真的很灵活,语法没有那么死板 1.int array[] = { 1, 2, 3, 4 };可以...

网友评论

    本文标题:数组_C语言

    本文链接:https://www.haomeiwen.com/subject/egikettx.html