C语言

数组_C语言

2016-09-03  本文已影响0人  MathCat

定义

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

数组名

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

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

这两者是等价的

int a[10];

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

初始化

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

int arr[5] = {0};
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;

上述声明后

作为函数参数的数组名

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

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

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;
            }
        }
    }

数组名

int matrix[2][3];

下标

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];

例:

以下为一个指针数组

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是字符的大小

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]);
    }
上一篇 下一篇

猜你喜欢

热点阅读