简单构造类型

一.一维数组

一维数组的定义与初始化

在C语言中,一维数组的定义和初始化可以通过以下方式进行:

  1. 在定义数组的同时进行初始化:

  2. int arr[5] = {1, 2, 3, 4, 5}; // 定义一个整型数组,并初始化5个元素
    

    只定义数组,稍后单独初始化:

  3. int arr[5]; // 定义一个整型数组,未初始化
    arr[0] = 1; // 初始化第一个元素
    arr[1] = 2; // 初始化第二个元素
    // ...可以逐个初始化其他元素
    

    使用指定值初始化数组:

  4. int arr[5] = {0}; // 所有元素初始化为0
    

    部分初始化,剩余元素自动填充为0:

  5. int arr[5] = {1, 2}; // 前两个元素初始化为1和2,其余自动初始化为0
    

    如果数组大小未知,可以通过初始化列表的元素个数来推断数组大小:

  6. int arr[] = {1, 2, 3, 4, 5}; // 数组大小为5
    

    在C语言中,数组的大小必须在编译时确定,且数组索引是从0开始到数组长度减1。访问未初始化的数组元素会导致未定义行为,而访问超出数组界限的元素也会导致未定义行为。

一维数组元素的引用

在C语言中,一维数组的引用主要通过数组名和下标来实现。

数组元素的基本概念

数组元素是组成数组的基本单元,其标识方法为数组名后跟一个下标。下标表示了元素在数组中的顺序号。数组元素的一般形式为:数组名[下标],其中下标只能为整型常量或整型表达式。如果下标为小数,C编译将自动取整‌。

引用一维数组的方法

在C语言中,只能逐个地使用数组下标变量,而不能一次引用整个数组。例如,输出有10个元素的数组必须使用循环语句逐个输出各下标变量:

 for(i=0; i<10; i++) printf("%d", a[i]);

而不能使用一个语句输出整个数组‌。

示例代码

以下是一个简单的示例代码,演示如何定义和引用一维数组:

#include <stdio.h>

int main() {
    int i, a[10]; // 正确声明一个长度为10的整数数组a
    for(i = 0; i < 10; i++) { // 注意循环条件应该是i < 10,而不是i <= 9,虽然在这个特定情况下两者效果相同
        a[i] = i; // 将数组的每个元素初始化为其索引值
    }
    for(i = 9; i >= 0; i--) {
        printf("%d\n", a[i]); // 逆序输出数组中的每个元素
    }
    return 0;
}

一维数组作为两组参数

在C语言中,一维数组可以用作两组参数:数组名和数组首地址。

一维数组的定义和初始化

在C语言中,一维数组的定义方式如下:

数组类型 数组名[常量表达式];

例如:

int arr;
char arr2‌:ml-citation{ref="1" data="citationList"};
float arr3‌:ml-citation{ref="2" data="citationList"};

这里的常量表达式表示数组的长度,即数组中元素的个数‌。

一维数组用作函数参数

在C语言中,一维数组用作函数参数时,实际上传递的是数组元素的首地址。函数可以接受数组名作为参数,也可以接受指向数组首元素的指针。例如:

void function(int arr[], int len);
void function(int *arr, int len);

这两种形式在编译时是等价的,因为函数会通过指针访问数组元素。函数内部不会检查数组的实际长度,因此调用者需要确保传递正确的长度参数‌。

一维数组的内存分配和访问

一维数组在内存中是连续存储的,数组的第一个元素的地址是&arr,第二个元素的地址是&arr‌:ml-citation{ref="5" data="citationList"},以此类推。数组的元素可以通过下标直接访问,下标从0开始计数。例如:

int arr‌:ml-citation{ref="1" data="citationList"} = {1, 2, 3, 4, 5};
printf("%d\n", arr‌:ml-citation{ref="6" data="citationList"}); // 输出3

这里arr‌:ml-citation{ref="6" data="citationList"}表示访问数组中的第三个元素,其值为3‌。

二.一维数组的应用

数据元素的复制与选择

#include <stdio.h>
 
// 函数原型声明
void copy_elements(int *dest, int *src, int n);
void select_elements(int *arr, int n, int flag);
 
int main() {
    int arr[5] = {1, 2, 3, 4, 5}; // 初始化一维数组
    int copy[5];                  // 用于复制元素的目标数组
 
    // 复制数组元素
    copy_elements(copy, arr, 5);
 
    // 根据条件选择数组元素
    select_elements(arr, 5, 1); // 假设flag为1,选择所有元素
 
    // 打印结果
    printf("原数组: ");
    for (int i = 0; i < 5; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n复制后数组: ");
    for (int i = 0; i < 5; i++) {
        printf("%d ", copy[i]);
    }
    printf("\n");
 
    return 0;
}
 
// 实现数组元素的复制
void copy_elements(int *dest, int *src, int n) {
    for (int i = 0; i < n; i++) {
        dest[i] = src[i];
    }
}
 
// 实现根据条件选择数组元素
// 这里假设flag为1时选择所有元素,未实现具体条件选择
void select_elements(int *arr, int n, int flag) {
    // 此处省略具体的选择逻辑
}

数据元素的移动

#include <stdio.h>
 
void move_element(int arr[], int n, int pos_from, int pos_to) {
    int temp = arr[pos_from]; // 保存要移动的元素
 
    // 如果目标位置大于源位置,先向后移动后续元素
    if (pos_to > pos_from) {
        for (int i = pos_from; i < pos_to; i++) {
            arr[i] = arr[i + 1];
        }
    } else { // 如果目标位置小于源位置,先向前移动后续元素
        for (int i = pos_from; i > pos_to; i--) {
            arr[i] = arr[i - 1];
        }
    }
 
    // 将元素移动到新位置
    arr[pos_to] = temp;
}
 
int main() {
    int arr[] = {1, 2, 3, 4, 5};
    int n = sizeof(arr) / sizeof(arr[0]);
 
    // 移动数组中的数据元素,例如将元素3从位置2移动到位置4
    move_element(arr, n, 2, 4);
 
    // 打印移动后的数组
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
 
    return 0;
}

在这个例子中,move_element 函数接受四个参数:数组 arr,数组的长度 n,要移动的数据元素的原始位置 pos_from,以及要将元素移动到的新位置 pos_to。函数内部通过循环将元素移动到正确的位置。最后,在 main 函数中调用 move_element 函数,并打印出移动后的数组,以验证结果。

数据元素的查找与统计

在C语言中,我们可以使用不同的方法来查找和统计数组中的元素。以下是一些常见的方法:

  1. 线性搜索:这是最简单和最基本的方法。我们只是遍历数组,并检查每个元素是否是我们正在寻找的元素。

  2. int linear_search(int arr[], int n, int x)
    {
        int i;
        for (i = 0; i < n; i++)
            if (arr[i] == x)
                return i;
        return -1;
    }
    
  3. 二分搜索:这种方法仅适用于已排序的数组。我们取数组的中间元素,如果它等于我们正在寻找的元素,我们完成。如果不是,我们根据中间元素将数组一分为二,然后在左半边或右半边继续进行二分搜索。

  4. int binary_search(int arr[], int low, int high, int x)
    {
        while (low <= high) {
            int mid = low + (high - low) / 2;
            if (arr[mid] == x)
                return mid;
            if (arr[mid] > x)
                high = mid - 1;
            else
                low = mid + 1;
        }
        return -1;
    }
    

    统计数组中的元素:我们只是遍历数组,并计算特定元素的出现次数。

  5. int count_element(int arr[], int n, int x)
    {
        int count = 0;
        for (int i = 0; i < n; i++)
            if (arr[i] == x)
                count++;
        return count;
    }
    

数据元素的修改、删除与插入

在C语言中,数组是一种常用的数据结构,它是固定大小的,一旦定义,你不能在数组的中间修改、删除或插入元素。但是,你可以通过创建新的数组来实现修改、删除和插入操作。

  1. 修改数组元素:

  2. #include <stdio.h>
     
    int main() {
        int arr[5] = {1, 2, 3, 4, 5};
        printf("Original array: ");
        for(int i = 0; i < 5; i++) {
            printf("%d ", arr[i]);
        }
        arr[1] = 10; //修改第二个元素
        printf("\nArray after modification: ");
        for(int i = 0; i < 5; i++) {
            printf("%d ", arr[i]);
        }
        return 0;
    }
    

    删除数组元素:

  3. #include <stdio.h>
     
    int main() {
        int arr[5] = {1, 2, 3, 4, 5};
        int element_to_delete = 3;
        int i, j;
        for(i = 0; i < 5; i++) {
            if(arr[i] == element_to_delete) {
                for(j = i; j < 4; j++) {
                    arr[j] = arr[j+1];
                }
                break;
            }
        }
        printf("Array after deletion: ");
        for(int i = 0; i < 4; i++) {
            printf("%d ", arr[i]);
        }
        return 0;
    }
    

    插入数组元素:

  4. #include <stdio.h>
     
    int main() {
        int arr[5] = {1, 2, 4, 5};
        int index = 2;
        int element_to_insert = 3;
        int i;
        for(i = 4; i >= index; i--) {
            arr[i] = arr[i-1];
        }
        arr[index] = element_to_insert;
        printf("Array after insertion: ");
        for(int i = 0; i < 5; i++) {
            printf("%d ", arr[i]);
        }
        return 0;
    }
    

数据的排序

在C语言中,对数组进行排序有多种方法,下面我将列出几种常见的排序方法及其代码实现。

  1. 冒泡排序

冒泡排序是一种简单的排序算法,它重复地遍历要排序的数组,一次比较两个元素,如果它们的顺序错误就把它们交换过来。重复进行直到没有再需要交换的元素,这意味着数组现在已经排序完成。

void bubble_sort(int arr[], int len) {
    int i, j, temp;
    for (i = 0; i < len - 1; i++)
        for (j = 0; j < len - 1 - i; j++)
            if (arr[j] > arr[j + 1]) {
                temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
}
  1. 选择排序

选择排序是一种简单直观的排序算法,无论什么数据进去都会进行排序,但是速度比冒泡排序快,所以在数据量大的时候可以选择。

void selection_sort(int arr[], int len) {
    int i, j, min, temp;
    for (i = 0; i < len - 1; i++) {
        min = i;
        for (j = i + 1; j < len; j++)
            if (arr[j] < arr[min])
                min = j;
        temp = arr[i];
        arr[i] = arr[min];
        arr[min] = temp;
    }
}
  1. 插入排序

插入排序的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

void insertion_sort(int arr[], int len) {
    int i, j, key;
    for (i = 1; i < len; i++) {
        key = arr[i];
        j = i - 1;
        while (j >= 0 && arr[j] > key) {
            arr[j + 1] = arr[j];
            j = j - 1;
        }
        arr[j + 1] = key;
    }
}
  1. 快速排序

快速排序使用分治法(Divide and conquer)策略来把一个序列分为两个子序列。

void swap(int* a, int* b) {
    int t = *a;
    *a = *b;
    *b = t;
}
 
int partition (int arr[], int low, int high) {
    int pivot = arr[high];
    int i = (low - 1);
 
    for (int j = low; j <= high - 1; j++) {
        if (arr[j] < pivot) {
            i++;
            swap(&arr[i], &arr[j]);
        }
    }
    swap(&arr[i + 1], &arr[high]);
    return (i + 1);
}
 
void quickSort(int arr[], int low, int high) {
    if (low < high) {
        int pi = partition(arr, low, high);
 
        quickSort(arr, low, pi - 1);
        quickSort(arr, pi + 1, high);
    }
}
  1. 归并排序

归并排序是一种稳定的排序算法,它每次都会归并两个已经排序好的序列。

void merge(int arr[], int l, int m, int r) {
    int i, j, k;
    int n1 = m - l;
    int n2 = r - m;
    int L[n1

三.二维数组及其应用

二维数组的定义与初始化

二维数组在C语言中是通过一维数组的嵌套来实现的,即一个一维数组的每个元素又被声明为一维数组,从而构成二维数组‌。二维数组的定义格式如下:

数据类型 数组名[常量表达式1][常量表达式2];

其中,常量表达式1表示第一维下标的长度,常量表达式2表示第二维下标的长度。

例:
定义一个3行4列的整型二维数组‌。

int score[3][4]

二维数组的初始化

二维数组可以在定义时进行初始化,初始化可以是对整个数组进行赋值,也可以是对数组中的部分元素进行赋值。

在定义时初始化:

int a[3][4] = {
    {1, 2, 3, 4},
    {5, 6, 7, 8},
    {9, 10, 11, 12}
};

先定义后逐个赋值:

int a[3][4];
int i, j;
for (i = 0; i < 3; i++)
    for (j = 0; j < 4; j++)
        a[i][j] = (i * 4) + j + 1;

字符串初始化:(适用于元素类型是字符或者是一些小的基本类型)

char a[3][10] = {
    "Hello",
    "World",
    "!"
};
char a[3][10] = {"Hello", "World", "!"};

如果二维数组的某些值是已知的,其余的部分你想用0来初始化,可以使用:

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

初始化结果为:

1 2 0 
5 0 0 0
0 0 0 0

如果你想创建一个二维数组,但是你不知道确切的大小,你可以使用动态分配内存:

(创建一个三行四列的二维数组)
 

int **a = malloc(sizeof(int*) * 3);
for (int i = 0; i < 3; i++)
    a[i] = malloc(sizeof(int) * 4);

注意:在使用动态分配内存的方法时,你需要手动释放内存,否则可能会导致内存泄漏

二维数组元素的引用

在C语言中,二维数组可以看作是数组的数组,即二维数组的每一个元素都是一个一维数组。因此,二维数组的元素可以通过下标来进行引用。

解法一:直接使用下标引用二维数组的元素。

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

解法二:使用指针引用二维数组的元素。(指针后面会讲,仅作了解)

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

二维数组作为函数参数

在C语言中,二维数组可以作为函数的参数进行传递。这里有两种常见的方法:

          使用静态二维数组

在这种情况下,需要在函数声明中指定数组的行和列的大小。

#include <stdio.h>
 
void print_arr(int arr[2][3]) {
    int i, j;
    for(i = 0; i < 2; i++) {
        for(j = 0; j < 3; j++) {
            printf("%d ", arr[i][j]);
        }
        printf("\n");
    }
}
 
int main() {
    int arr[2][3] = {{1, 2, 3}, {4, 5, 6}};
    print_arr(arr);
    return 0;
}
  1. 使用动态分配的二维数组

在这种情况下,可以在函数声明中只指定一个维度,并在函数调用时动态分配数组。

#include <stdio.h>
#include <stdlib.h>
 
void print_arr(int **arr, int m, int n) {
    int i, j;
    for(i = 0; i < m; i++) {
        for(j = 0; j < n; j++) {
            printf("%d ", arr[i][j]);
        }
        printf("\n");
    }
}
 
int main() {
    int i, j;
    int m = 2, n = 3;
    int **arr = (int **)malloc(m * sizeof(int *));
    for(i = 0; i < m; i++) {
        arr[i] = (int *)malloc(n * sizeof(int));
        for(j = 0; j < n; j++) {
            arr[i][j] = i * n + j + 1;
        }
    }
    print_arr(arr, m, n);
    for(i = 0; i < m; i++) {
        free(arr[i]);
    }
    free(arr);
    return 0;
}

四.字符数组与字符串

在C语言中,字符串和字符数组是两个常用的数据类型,但它们之间有一些重要的区别。

  1. 定义方式不同:字符串是字符数组的一种特殊情况,在C语言中,字符串常量是字符数组的一个实例,其特点是以'\0'(空字符)结尾。

例如:

char str[] = "Hello"; // 这是一个字符数组

char *p = "Hello"; // 这是一个字符串常量(字符串字面量)

存储位置不同:字符串常量存储在常量区,而字符数组如果不是全局或静态的,则存储在栈或堆上。

例如:

char str[] = "Hello"; // "Hello"存储在栈上,str[]是数组的副本

char *p = "Hello"; // "Hello"存储在常量区,p是指向它的指针
  1. 内容不可变性:字符串常量的内容是不可以被修改的,如果尝试修改,程序会发生段错误(segmentation fault)。但是字符数组的内容是可以修改的。

例如:

char str[] = "Hello";

str[0] = 'h'; // 正确,修改数组内容

char *p = "Hello";

p[0] = 'h'; // 错误,尝试修改字符串常量的内容,会导致段错误
  1. 长度计算方式不同:字符串的长度可以通过strlen()函数计算,字符数组的长度需要手动计算。

例如:

char str[] = "Hello";

int len_str = strlen(str); // 计算字符串长度

char p[] = "Hello";

int len_p = sizeof(p) / sizeof(p[0]); // 计算字符数组长度
  1. 初始化方式不同:字符串常量初始化通常使用双引号,字符数组可以使用单引号或者双引号,但是需要注意,使用单引号时,字符数组的长度为1,内容为单引号中的字符。

例如:

char str[] = {'H', 'e', 'l', 'l', 'o', '\0'}; // 显式初始化字符数组

char str1[] = "Hello"; // 隐式初始化字符数组

const char *p = "Hello"; // 字符串常量指针

字符数组的定义,初始化,引用

在C语言中,字符数组主要用于存储字符数据,可以是字符串,也可以是单个字符。字符数组的定义、初始化和引用方法如下:

  1. 定义字符数组:

char charArray[size];

其中,charArray是数组名,size是数组的大小,可以是常量或者常量表达式,字符数组的大小从1开始。

  1. 初始化字符数组:

char charArray[size] = {'v', 'a', 'l', 'u', 'e', '1'};

或者

char charArray[size] = "value1";

其中,单引号内的是字符,双引号内的是字符串。

  1. 引用字符数组:

charArray[index];

其中,index是数组的索引,从0开始。

例如:

#include <stdio.h>

int main() {

// 定义字符数组

char charArray[6];

// 初始化字符数组

charArray[0] = 'v';

charArray[1] = 'a';

charArray[2] = 'l';

charArray[3] = 'u';

charArray[4] = 'e';

charArray[5] = '2';

// 或者使用一行代码初始化

// char charArray[6] = "value2";

// 引用字符数组

printf("%c\n", charArray[0]); // 输出v

printf("%s\n", charArray); // 输出value2

return 0;

}

以上代码定义了一个大小为6的字符数组,并对其进行了初始化,然后通过索引引用了数组中的一个元素,并输出了整个数组的内容。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值