七天入门C语言之第二天:数组与字符串

七天入门C语言之第二天:数组与字符串

今天,我们来学习两种新的数据类型,数组与字符串。

首先,顾名思义,数组,指的是由许多个数字组成的集合,也可以用数学上数列的概念来理解。而字符串,也很容易理解,就是由n个字符组成的字符串。那么,接下来我们来具体学习数组与字符串的实现,和一些相关的功能函数。

一、数组

  1. 声明数组: 在C语言中声明数组需要指定数组元素的类型和数组的名称。例如:

    int numbers[5];
    

    声明了一个整型数组 numbers,它可以存储5个整数,这5个整数会被分配到五个连续的存储空间里面,我们也可以说,它们具有连续的地址。

    与整型浮点型数字的声明一样,要先说明数组里面存放的数据类型,这里是 int 。当然,我们也可以使用double来声明一个浮点数数组。

  2. 数组下标的解释:

    首先,我们知道,在数学的数列知识里面,一个有5项的数列an,我们可以分别用a1、a2…a5来表示这五个数字。但是在计算机之中,这样的行为是错误的,在数组a之中,第一个数字必须用a[0]来表示。换句话说,数组a[5]存放的五个数字,需要分别使用a[0]、a[1]、a[2]、a[3]、a[4]来表示,而一旦使用a[5]就会产生段错误(即数组越界),这时编译器会显示Segmentation Fault。

    注意:数组越界是段错误的一种,段错误还包括空指针引用,内存未释放等多种错误,我们在后续的学习之中会学到。

  3. 初始化数组: 数组可以在声明时或稍后进行初始化。你可以使用大括号 {} 来为数组元素赋初值。例如,int numbers[5] = {1, 2, 3, 4, 5}; 初始化了一个整型数组 numbers,并将其前五个元素设置为1,2,3,4和5。

    int numbers[5] = {1,2,3,4,5};
    
  4. 访问数组元素: 数组的元素可以通过索引访问,索引从0开始。使用方括号 [ ] 加上索引值,可以获取或修改数组的特定元素。例如,

    int x;
    x = numbers[2];
    

    可以实现 将数组 numbers 的第3个元素赋值给变量 x

  5. 数组长度: 数组的长度是在声明时指定的,除了直接看[ ]内部的数字,还可以通过数组的长度属性 sizeof 来获取。例如,int size = sizeof(numbers) / sizeof(numbers[0]); 将数组 numbers 的长度除以单个元素的长度,得到数组的元素个数。
    注:sizeof()运算符,用于获取操作对象的长度。比如int类型的整数长度为4,char类型的字符长度为1。使用的时候可以用变量名,如:

    int a;
    printf("%d",sizeof(int));
    printf("%d",sizeof(a));
    //这两个表达式输出的结果都是4
    
  6. 数组遍历: 可以使用循环结构(如 for 循环)遍历数组的所有元素,并对它们进行操作。你可以使用数组的长度属性来控制循环的迭代次数。

    例如:

    #include <stdio.h>
    
    int main() {
        int numbers[] = {10, 20, 30, 40, 50};
        int length = sizeof(numbers) / sizeof(numbers[0]);
    
        printf("Array elements: ");
        for (int i = 0; i < length; i++) {
            printf("%d ", numbers[i]);
        }
        printf("\n");
    
        return 0;
    }
    
    
  7. 多维数组: C语言支持多维数组,如二维数组、三维数组等。多维数组可以通过使用多个索引值来访问其元素。例如,int matrix[3][3]; 声明了一个3x3的整型二维数组(在一些题目中也会称之为矩阵)。

  8. 数组的输入与输出:通过6的例子,我们知道数组可以通过循环结构的遍历来访问每一个值并输出,那么同理,我们同样也可以使用循环结构的遍历来为数组赋值。

    #include<stdio.h>
    
    int main()
    {
        int numbers[5];  //声明了一个长度为5的数组
        int i;           //声明变量i记录循环,并作为数组下标参与赋值和访问
        for(i=0;i<5;i++){
            scanf("%d",&numbers[i]);
        }
        for(i=0;i<5;i++){
            printf("%d",numbers[i]);
        }
        return 0;
    }
    

    可自己在编译器中运行该代码,可以实现输入五个数并输出。

  9. 初识分配数组:以上的举例都是建立在已知数组长度的情况下,比如说声明长度为5的数组,我们直接声明numbers[5],但是,在有些题目之中,出题者希望我们通过输入一个数值来作为数组的长度。

    例如:输入m作为数组numbers的长度,然后依次输入m个数字存放到数组中

    #include<stdio.h>
    
    int main()
    {
        int m;
        scanf("%d",&m);  //声明变量m用于记录输入的数组长度
        int numbers[m];  //声明了一个长度为m的数组
        int i;           //声明变量i记录循环,并作为数组下标参与赋值和访问
        for(i=0;i<m;i++){
            scanf("%d",&numbers[i]);
        }
        for(i=0;i<m;i++){
            printf("%d",numbers[i]);
        }
        return 0;
    }
    

    以上是使用静态分配方式的实现,可以使用数组声明语法直接在栈上分配数组内存。

    这种方式在编译时确定数组的大小,并将内存自动分配给数组。数组的生命周期与所在的作用域相关联,当离开作用域时会自动释放内存。

    虽然这种办法看似简单易懂,但是其背后也隐藏了许多潜在问题,例如,可能会导致栈的溢出,调用时会复制整个数组等。为了解决这种问题,我们在后续的学习中会引入malloc等动态分配内存的方法(等到指针的学习之后再说)

二、字符串

学习C语言字符串是非常重要的,因为字符串在各种应用程序中广泛使用。在C语言中,字符串是由字符组成的数组,并以空字符 ‘\0’ 结尾。

在进入字符串的学习之前,我们要新引入一个头文件string.hstring.h是C语言标准库中的一个头文件,它提供了一系列处理字符串的函数和常量的声明。通过包含 string.h 头文件,可以在程序中使用这些字符串相关的功能。

  1. 字符串的声明和初始化: 字符串可以通过字符数组或指针来表示和操作。下面是两种常见的声明和初始化字符串的方式:

    char str1[] = "Hello"; //使用字符串数组(声明时直接赋值就可以不用在[]中加长度,否则需要声明时加上长度再赋值)
    
    char *str2 = "World";  //使用字符串指针(可以等到学习指针之后再掌握这种方法)
    
  2. 字符串赋值: 字符串的赋值通常有两种办法。

    第一种办法是使用 = 赋值运算符进行初始化赋值,例如:

    #include <stdio.h>
    #include <string.h>
    
    int main() {
        char source[] = "Hello, World!";        // =赋值运算符为字符串source赋值
    
        // 输出结果
        printf("Source string: %s\n", source);
    
        return 0;
    }
    
    

    第二种办法是使用string.h头文件之中包含的函数strcpy来将一个字符串的值拷贝到另一个字符串,例如:

    #include <stdio.h>
    #include <string.h>
    
    int main() {
        char source[] = "Hello, World!";        // 源字符串
        char destination[20];                   // 目标字符串,需要足够的空间来存储源字符串
        
        // 使用 strcpy 函数将源字符串复制到目标字符串
        strcpy(destination, source);
        
        // 输出结果
        printf("Source string: %s\n", source);
        printf("Destination string: %s\n", destination);
        
        return 0;
    }
    
    
  3. 字符串输入和输出: 字符串的输入输出有多种办法。

    第一种办法,使用标准库函数进行字符串的输入和输出操作。例如:

    • printf("String: %s", str); 可以将字符串输出到控制台。
    • scanf("%s", str); 可以从用户输入中读取字符串。

    第二种办法,使用gets()、fgets()、puts()函数实现字符串的输入输出,例如:

    使用gets()函数与puts()函数

    #include <stdio.h>
    
    int main() {
        char str[50];
        
        printf("Enter a string: ");
        gets(str); // 输入字符串
        
        printf("You entered: ");
        puts(str); // 输出字符串
        
        return 0;
    }
    
    

    上面的示例中,我们使用 gets() 函数从用户获取输入字符串,并使用 puts() 函数将字符串输出到屏幕上。但是请注意,gets() 函数存在安全性问题,因为它无法限制输入字符串的长度,可能导致缓冲区溢出。所以在实际开发中,推荐使用更安全的 fgets() 函数。(如果有同学使用gcc编译过使用gets()函数的程序就会知道,系统会报出waring,这不是bug,但是系统会认为不安全,就像PTA平台的scanf返回值未调用一样)。

    使用fgets()函数与puts()函数

    #include <stdio.h>
    
    int main() {
        char str[50];
        
        printf("Enter a string: ");
        fgets(str, sizeof(str), stdin); // 输入字符串
        
        printf("You entered: ");
        puts(str); // 输出字符串
        
        return 0;
    }
    
    

    在上面的示例中,使用 fgets() 函数从标准输入(stdin)获取输入字符串,并将其存储在 str 字符数组中。sizeof(str) 用于指定输入字符串的最大长度,以确保不会发生缓冲区溢出。然后,使用 puts() 函数将字符串输出到屏幕上。

    再次提示,sizeof()运算符我们在数组的学习之中已经学习过,它用于获取目标的长度,因为字符串之中每个字符都是char类型的,长度为1,所以可以直接使用sizeof(str)来代表字符串的长度。而数组之中的int型长度为4,所以sizeof(数组名称)之后要除以4(也就是sizeof(int))才能获取数组的长度。

  4. 字符串长度: 除了刚才说的使用sizeof()运算符可以获取字符串长度,我们还可以使用标准库函数 strlen 可以获取字符串的长度(不包括空字符 ‘\0’)。例如:int length = strlen(str);

    当然,使用strlen()函数之前要先导入头文件string.h

  5. 字符串连接: 使用标准库函数 strcat 可以将一个字符串连接到另一个字符串的末尾。

    例如:strcat(str1, str2);str2 连接到 str1 的末尾。

  6. 字符串比较: 使用标准库函数 strcmp 可以比较两个字符串的大小。

    例如:int result = strcmp(str1, str2); 将返回一个整数值,表示字符串的比较结果。

  7. 字符串搜索和替换: 使用标准库函数进行字符串搜索和替换操作。例如:

    • strstr(str, pattern); 可以在字符串中搜索子字符串,并返回第一次出现的位置。
    • strchr(str, ch); 可以在字符串中查找指定字符,并返回第一次出现的位置。
    • strreplace(str, old, new); 可以将字符串中的指定子串替换为新的子串。

    以上这些最后提到的函数可以在自己刷题的时候多尝试使用不同的方法。

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值