C 数组

程序中定义数组是为了实现将离散变量变为连续变量(变量内存单元连续),利用循环使程序处理简单化。

 

一、一维数组

定义与赋值

char arr[10];
// 循环赋值
for (int i = 0; i < 10; ++i) {
    arr[i] = 'A' + i;
}
for (int i = 0; i < 10; ++i) {
    printf("%c\t", arr[i]);
}

// 直接赋值,未赋值元素默认为 0
short int a[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
for (int i = 0; i < 10; ++i) {
    printf("%d", a[i]);
}

// 数组长度为 3
short int b[] = {1, 2, 3};

// 数组不初始化,元素为随机值
short int c[];

 

通过地址取值

char arr[10];
for (int i = 0; i < 10; ++i) {
    arr[i] = 'A' + i;
}

// 直接打印变量名为数组第一个元素的指针,取指定元素的地址 &arr[5]
printf("\n%p", a);

for (int i = 0; i < 10; ++i) {
    printf("%c\t", *(arr + sizeof(char) * i));
}

 

初始化和拷贝

#include <stdio.h>
#include <string.h>

int main() {
    char arr[10];

    // 初始化,全部赋值为 A
    memset(arr, 'C', 10 * sizeof(char));

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

    printf("\n");

    char cpy[10];
    // 拷贝前 5 个,后 5 个未赋值的为空(已初始化)
    memcpy(cpy, arr, 5 * sizeof(char));
    for (int i = 0; i < 10; ++i) {
        printf("%c\t", cpy[i]);
    }

    return 0;
}

 

二、多维数组

定义与赋值

// 数组的维数上限仅受编译程序限制
// 二维数组的元素是一个一维数组
// 二维数组物理上按行存储
// a[0] -> a[0][0],a[0][1],a[0][2]
// a[1] -> a[1][0],a[1][1],a[1][2]

// 未赋值默认为 0
// 不允许 int arr[2][3] = {{},{5, 6}}; 至少要有一个元素
int arr[2][3] = {{1},{5, 6}};

// 等同定义 arr[2][3]
int arr[][3] = {{1, 2, 3},{4, 5, 6}};

// 等同于 int arr[2][3] = {1, 2, 3, 4, 5, 6};
// 等同于 int arr[][3] = {1, 2, 3, 4, 5, 6};
int arr[2][3] = {{1, 2, 3},{4, 5, 6}};

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

// 二维数组变量名是数组所占内存空间的首地址
// 也就是第一个元素的指针
printf("%p", arr);

 

三、字符串与数组

字符串是一种以 \0 结尾的数组

   ASCII:  0x63  0x68  0x69  0x6e  0x61    0
对应字符串:   c     h     i     n     a     \0

定义与赋值

// 会自动添加 \0,数组大小为 6
char str[] = "china";
// 手动添加 \0,数组大小为 6
char str[] = {'c', 'h', 'i', 'n', 'a','\0'};
// 会自动添加 \0,,数组大小为 6
char str[] = {"china"};

// 没有 \0,数组大小为 5
char str[] = {'c', 'h', 'i', 'n', 'a'};

// 错误语法,str 是地址常量,不可赋值,"china" 的值是该字符串常量在内存中的地址,本身并不是字符序列
// 字符串常量只能在定义字符数组变量时赋初值给字符数组变量,而不能将一个字符串常量直接赋值给字符数组变量
// 如果要将一个字符串常量赋值给一个字符数组变量,需要 C 语言标准库函数
char str[10];
str = "chain";


// 数组大小为 10,未指定单元的值为 0
char str[10] = "china";
char str[10] = {'c', 'h', 'i', 'n', 'a','\0'};


for (int i = 0; i < 6; ++i) {
    printf("%c\t", str[i]);
}

Note:字符数组存放字符串常量时,如果指定字符数组大小,其大小要比字符串长度大一个,用于存放 ‘\0’

 

字符及字符串常用函数

输入

#include <stdio.h>

char str[10];

// 能接受包含空格的字符串
// 超过数组长度之外的内容保存在数组之外的内存单元中,可能覆盖其它内存变量的内容
// 回车结束,不会存储 '\n',会将回车转换为 '\0'
gets(str);

char str2[10];
// 会忽略前导空格
// 空格或回车结束(即字符串不能输入空格),会自动在字符串后加 '\0'
// 避免长度问题,使用 %ns 格式控制符
scanf("%9s%9s", str, str2);

输出

// 会将 '\0' 转换为 '\n'
// 无法控制格式
puts(str);

// 遇到 '\0' 结束,'\0' 不会被输出
// 可以控制输出格式
printf("%s", str);

长度

#include <string.h>

// \045 作为一个转义字符看待
char str[] = "0123\0456789";
printf("%llu", strlen(str)); // 9
printf("%llu", strlen(&str[5])); // 4

复制

char str1[] = "0123456789";
char str2[11];

// 数组 2 大小必须足够存放字符串 1,包括字符串 1 中的 '\0'
strcpy(str2, str1);

// 复制前两个字符,并添加 '\0'
strncpy(str2, str1, 2);

memcpy(str2, str1, strlen(str1) * sizeof(char));

比较

char str1[] = "ABC";
char str2[] = "ABD";;

// ASCII 比较
// 1>2为正数,1<2为负数,1=2为0
if (strcmp(str1, str2) == 0) {
    printf("%s", "===");
}
// 不区分大小写
stricmp(str1, str2);

// 只比较前两个字符
strncmp(str1, str2, 2);
// 不区分大小写
strnicmp(str1, str2, 2);

连接

char str1[7] = "ABC";
char str2[] = "ABD";;

// 2 连接到 1 后面(包括 '\0'),2 不变,1 中字符增加
// 1 数组应足够大
strcat(str1, str2);

 

字符串数组

char city[][10] = {"Beijing", "ShangHai", "TianJin", "GuangZhou", "WuHan"};
for (int i = 0; i < strlen(city); ++i) {
    puts(city[i]);
}

 


https://www.gnu.org/software/libc/manual/html_node/String-and-Array-Utilities.html#String-and-Array-Utilities

posted @ 2020-11-06 10:44  江湖小小白  阅读(263)  评论(0编辑  收藏  举报