C语言数组

"最简单的数据结构"

Posted by wanglilong on December 10, 2018

C语言数组

从事开发工作已经五年多了,现在决定复习数据结构与算法。大学里学习算法的时候用的是C语言,现在还是感觉使用C语言来学习算法更顺手一点。

既然决定学习数据结构,就从最简单的开始,即数组。工作中还是经常使用数组的,数组分为可变的与不可变的,不可变的数组要简单很多,没有什么可说的。可变的数组在现代的语言中是直接支持的,但是数组c语言并不支持,需要自己开发。

根据常用的数组功能,准备实现以下功能:
1、数组中任意位置添加元素
2、数组中删除任意元素
3、数组尾部添加元素

一、工具准备

打印数组

只简单打印数组即可,实现起来很简单实现。

但是数组尾部的判断有问题,在新版的c语言中\0和数字0竟然是一个ASCCI数值。
所以这个数组中不能含有0,不然会在数字零处停止打印。

1
2
3
4
5
6
7
void printArray(int array[]) {
  int i = 0;
  while (array[i]!='\0') {
    printf("%d",array[i++]);
  }
  printf("\n------------------\n");
}

判断数组大小

网上查到判断数组大小的代码如下:

1
length = sizeof(array) / sizeof(int);

但是当数组作为实参传递到另一个函数时, 用上述方法返回的是一个固定值,猜测可能是c语言将传过来的数组作为指针处理了。

所以没办法只能用土办法:

1
2
3
4
5
6
7
8
9
10
int size(int array[]){
  if (!array){
    return 0;
  }
  int i = 0;
  while (array[i] != '\0') {
     i++;
  }
  return i;
}

二、实现数组增删数值

在指定位置添加数值

在指定的位置添加数字,主要逻辑是,将指定位置以及之后所有的数字向后移一位,将要插入的数字放在指定的位置。 但是第一次实现时while循环里,这么写的:

1
2
3
4
  while (i > index) {
    array[i] = array[i--];
  }

然而c语言是从又向左执行的,它和array[i-1] = array[i]是等价的。所以出来的结果完全错误。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//  add a number to array in the index
int addIn(int array[],int index, int num){
    if (!array) {
      array[0] = num;
      return 0;
    }else if(index > size(array)){
      printf("out index");
      return 0;
    }else{
      array[size(array)+1] = '\0';
      int i = size(array);
      while (i > index) {
        array[i] = array[i-1];
        i--;
      }
      array[i] = num;
      return 1;
    }
}
// add a number to array in the end
int add(int array[],int num){
    addIn(array,size(array),num);
}

删除指定位置的数值

删除元素和添加元素类似,删除指定位置的数字,之后的所有元素向前移动一位。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// delete a number from array
int delete(int array[],int index){
    if (!array) {
      printf("array have no data");
      return 0;
    }else if (index >= size(array)) {
      printf("index out of array");
      return 0;
    }else{
      int i = index;
      while (array[i+1] != '\0') {
        array[i] = array[i+1];
        i++;
      }
      array[i] = '\0';
      return 1;
    }
  }

三、总结

简单测试一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int  main(int argc, char const *argv[]) {
  int array[10] = {1,2,'\0'};
  printArray(array);
  printf("array end add 3\n");
  add(array,3);
  printArray(array);

  printf("array start with 4\n");
  addIn(array,0,4);
  printArray(array);

  printf("delete the first\n");
  delete(array,0);
  printArray(array);
  return 0;
}

结果符合预期

当然这并不是一个真正意义上的动态数组,因为当它超过初始数组长度的时候会出错

如果这个数组非常大的时候,在首位添加或者删除一个元素的时会移动很多数据,这样消耗会很大。所以对于大一点的数据,如果需要添加或删除,选用数组就不是一个明智的选择。这也许是另外一个基础数据结构链表诞生的原因之一。