嵌入式开发学习(第二阶段 C语言基础)

字符数组

在C语言中,支持常量字符串,不支持变量字符串如果想要实现类似的字符串,C语言提供了两种实现方式:

  • 字符数组
char name[] = '哪吒'
  • 字符指针
char *name = '哪吒'
概念

**元素类型char(字符型)的数组叫做字符数组。**字符数组往往是用来存储字符串数据的。需要注意的,我们C语言中的字符是字节字符(1字符 = 1字节,C语言中没有字节这个表示法,我们一般使用char表示字节1char= 8Bit )

硬件中存放数据以bit(位)为单位,系统对于内存的操作以char(字节)为单位。系统为内存以1个字节为单位进行编号。

实验:

char a = 'A';//正确
char b = '1';//正确
char c = 56; //正确,这里的65是ASCII码,char的值有两种表示形式,一种是字符,一种是字符对应的ASCII码
char d = "A";//错误,用双引号包裹的内容是常量字符串(没有变量字符串)
char e = '王';//错误,ASCII中不包含中文字符,中文字符使用的是如GBK、UTF-8等编码,实际上都超过了1个字节
语法

一维数组:

char 数组名[数组容量]

二维数组:

char  数组名[行容量][列容量]

字符数组的语法就是我们之前所学的一维数组和二维数组的语法,只不过数据类型是char而已。

注意:

​ 如果我们的char数组初始化的时候,没有完全初始化值的时候,使用\0进行填充。大家要注意,这里的\0只是起到一个占位或者标识的作用,我们是无法通过printf等打印输出到控制台的(不支持输出)。

比如:

char c[8] = {'h','g','i','u'}      //部分初始化
char c[8] = {'h','g','i','u','\0','\0','\0','\0'}
案例
案例1
  • 需求:输出一个字符序列(I LOVE YOU)

  • 代码

    /*************************************************************************
      > File Name:    demo04.c
      > Author:       小刘
      > Description:  
      > Created Time: 2025年05月16日 星期五 22时20分12秒
     ************************************************************************/
    
    #include <stdio.h>
    
    int main(int argc,char *argv[])
    {
    	 // 创建一个数组,用来存储 I LOVE YOU,ASCII中对应的空格为 ' ',其对应的ASCII码是 32
    
        char arr[] = {'I',' ','L','O','V','E',32,'Y','O','U'};
        // 计算数组的大小
    
        int len = sizeof(arr) / sizeof(arr[0]);
        // 使用for循环遍历数组
    
        for (int i = 0; i < len; i++) printf("%c",arr[i]);
        printf("\n");
    
        return 0;
    }
    

案例2

  • 需求:输出一个用字符*组成的菱形图案

  • 代码:

    /*************************************************************************
      > File Name:    demo05.c
      > Author:       小刘
      > Description:  打印一个菱形
      > Created Time: 2025年05月13日 星期二 13时09分28秒
     ************************************************************************/
    
    #include <stdio.h>
    
    int main(int argc,char *argv[])
    {
        //创建一个二维数组,存放空菱形
        int arr[5][5] = {
        ' ',' ','*',' ',' ',
        ' ','*',' ','*',' ',
        '*',' ',' ',' ','*',
        ' ','*',' ','*',' ',
        ' ',' ','*',' ',' ',
        };
    
        //计算行数和列数
         int row = sizeof(arr) / sizeof(arr[0]);
         int col = sizeof(arr[0]) / sizeof(arr[0][0]);
    
         for(int i = 0;i < row ;i++)
         {
             for(int j = 0;j < col ;j++)printf("%c",arr[i][j]);printf("\n");
         }
        printf("\n");
        return 0;
    }
    
注意
  • 如果定义时,不初始化,元素值不确定(针对局部定义的数组)
char arr1[2]//如果这个数组是定义在函数中的,此时元素的值是随机的
char arr2[5]= {'a','b','c'}; //此时属于不完全初始化,未初始化完的元素使用\θ填充
  • 如果提供的字符个数大于数组长度,则按照语法错误处理(会报警告,但是能编译通过);如果字符个数小于数组长度,后面的元素自动补\0

    char arr1[2] = {'h','e','e'}; //编译通过,但是会报警告,不建议写
    char arr2[3] = {'a'};         //正确的,未初始化的元素使用’\θ”填充
    
  • 如果提供的字符个数与数组长度相同,可以省略数组长度,系统会自动确定元素个数,适合字符较多时。

    char arr1[] = {'b','u'}; //正确,根据初始化元素,由系统自动计算元素个数
    
字符串的结束标志
说明
  • C 语言规定,字符串以字符\0,作为结束标志。

  • 编译系统对字符串常量自动加一个\0作为结束的标志。比如char *name = "TOM",实际上存储为{‘t’,‘o’,‘m’,‘\0’}

  • 程序中往往通过判断\0来检测字符是否结束。举例:while(arr[i]! = ‘\0’){…}

  • \0的ASCII码是0,不是一个可显示可输出的字符,是“空操作符”,它什么都不做,不会增加有效字符,仅仅用作一个工程判别的标志或者在字符数组中占位。

    char a[] = {'h','i'};        //遍历hi
    char a[] = {'h','i','\0'};   //遍历hi
    char a[] = "hello";          //遍历hello\0   字符串常量,在内存中,默认加了一个\0字符作用结尾标志
    
字符串的多样表示

我们的char 数组的形式一个一个输出每一个字符;也可以以字符串的形式整体输出。

  • 演示

    /*************************************************************************
      > File Name:    demo07.c
      > Author:       小刘
      > Description:  
      > Created Time: 2025年05月17日 星期六 16时56分20秒
     ************************************************************************/
    
    #include <stdio.h>
    
    int main(int argc,char *argv[])
    {
        // 字符串的第1种表示:
    
        char s1[] = {'h','e','l','l','o',' ','w','o','r','l','d','\0'};
        // 字符串的第2种表示:
    
        char s2[] = {"hello world"}; // "" 包裹的字符串一般默认有一个\0,所以不需要我们手动添加
    
        // 字符串的第3种表示:
    
        char s3[] = "hello world";
        
        // 计算字符串所占的字节数
    
        printf("s1=%d,s2=%d,s3=%d\n", sizeof(s1), sizeof(s2), sizeof(s3)); //s1=12,s2=12,s3=12
    
        // 字符串输出第1种方式:
    
        int len = sizeof(s3) / sizeof(s3[0]);
        for (int i = 0; i < len; i++)
       {
            // 过滤\0
    
            if (s1[i] == '\0' || s2[i] == '\0' || s3[i] == '\0') continue;
            printf("%c,%c,%c\n",s1[i], s2[i], s3[i]);
       }
        printf("\n");
        
        // 字符串输出第2种方式:
    
        printf("%s,%s,%s\n",s1, s2, s3);
        printf("\n");
    
        return 0;
    }
    
  • 运行结果:

在这里插入图片描述

注意:

  • 字符串的长度与字符数组的长度不一定形同。
char *name = "hello"; //数组长度:6,字符串长度:5
  • 利用字符串常量可以对字符数组进行初始化,但不能用字符串常量对字符数组赋值。

    // 正确演示:利用字符串常量给字符数组初始化
    char arr1[] = "hello";
    
    // 错误演示:利用字符串常量给字符数组赋值
    char arr2[6];
    arr2 = "hello";  // 可以理解为,数组是一个常量
    
字符串的基础操作

在用格式化说明符%s进行输入输出,其输入输出项均为数组名。但是在输入时,相邻两个字符串之间要用空格分隔,系统将自动在字符串后加\0。在输出时,遇到结束符\0作为输出结束标志。

对于字符串的操作,我们需要使用到一些系统提供的API函数。

字符串输入

scsnf

语法:

scanf("%s",数组名);

注意:数组名对应的数组只能是char类型,从控制台输入字符串之后,默认为追加\0

案例:

#include <stdio.h>

int main(int argc,char *argv[])
{
    // 创建一个字符数组,用来存储姓名
    char name[20]; // 初始化的时候,数组容量可以省略,char name[] = {..},如果只是声明,数组容量不能省略
    // 计算数组容量
    int len = sizeof(name) / sizeof(name[0]);
    
    printf("请输入您的名字:\n");
    // scanf("%s",name);// 数组本身没有空间,它的内存空间其实就是其元素空间,C语言规定数组名指向第一个元素的首地址

    fgets(name,len,stdin); 
    printf("您的姓名是:%s\n",name);
    
    return 0;
}

注意:采用scanf进行字符串输入,要求字符串中不能有空格,否则字符串遇到空格就会结束。

fgets

语法:

fget (数组名,数组容量,stdin);

功能:

​ 从键盘录入一个字符串常量到字符数组,返回字符数组的地址(首地址,默认返回的地址,一 般用12位16进制数表示)

说明:

​ 采用fgets进行字符串输入,可获取所有输入的字符串,包含\n,在实际的字符串处理时,我们 可能需要手动处理\n

#include <stdio.h>

int main(int argc,char *argv[])
{
    // 创建一个字符数组,用来存储姓名

    char name[20]; // 初始化的时候,数组容量可以省略,char name[] = {..},如果只是声明,数组容量不能省略

    // 计算数组容量

    int len = sizeof(name) / sizeof(name[0]);
    printf("请输入您的名字:\n");
    // scanf("%s",name);// 数组本身没有空间,它的内存空间其实就是其元素空间,C语言规定数组名指向第一个元素的首地址

    fgets(name,len,stdin); 
    printf("您的姓名是:%s\n",name);
	return 0;
}

注意:

① 如果输入的字符串不包括空格或换行,可以使用scanf或者fgets

② 如果输入的字符串包括空格或换行,只能使用fgets

gets危险的【C11移出】

语法:

gets(数组名);

功能:

​ 从键盘录入一个字符串常量到字符数组,返回字符数组的地址(首地址,默认返回的地址,一 般用12位16进制数表示)

说明:

​ 采用gets进行字符串输入,可获取所有输入的字符串,包含 \n ,在实际的字符串处理时,我 们可能需要处理 \n

 #include <stdio.h>
 
 int main(int argc,char *argv[])
 {
     // 创建一个字符数组,用来存储姓名
     char name[20];
 
     printf("请输入您的名字:\n");
     scanf("%s",name);// 数组本身没有空间,它的内存空间其实就是其元素空间,C语言规定数组名指向的就是首地址

     printf("您的姓名是%s\n",name);
     return 0;
 }
字符串输出

printf

语法:

printf("%s",数组名);

案例:

 #include <stdio.h>
 
 int main(int argc,char *argv[])
 {
     // 创建一个字符数组,用来存储姓名
     char name[20];
 
     printf("请输入您的名字:\n");
     scanf("%s",name);// 数组本身没有空间,它的内存空间其实就是其元素空间,C语言规定数组名指向的就是首地址

     printf("您的姓名是%s\n",name);
     return 0;
 }

fputs

语法:

注意:采用scanf进行字符串输入的时候不能采用空格,否则遇到空格会结束

语法:

fputs(数组名,stdout);

功能:

​ 输出一个字符串

说明:

​ 字符串可以包含转义字符(以\开头的字符)

案例:

#include <stdio.h>

int main(int argc,char *argv[])
{
    char arr[] = "hi lucy\trun!\n";
    
    // 第1种输出
    printf("%s",arr);
    
    // 第2种输出
    fputs(arr,stdout);
    return 0;
}

puts危险的【C11移出】

语法:

puts(数组名称);

功能:

​ 输出一个字符串

说明:

​ 字符串可以包含转义字符

案例:

#include <stdio.h>
  
  int main(int argc,char *argv[])
 {
      // 创建一个数组,用来存放人的名字
      char name[20];
  
      printf("请输入您的名字:\n");
      // gets、fgets和scanf只能多选一
      gets(name);
  
      // 输出
      puts(name);// 标准的输出
      return 0;
 }
字符串转数值【扩展】
  • strtol

    long strtol(const char *str, char **endptr, int base);
    

    将字符串转换为长整型数。

    参数说明:

    • str :指向要转换的字符串的指针。
    • endptr :一个指向字符指针的指针。如果提供了这个参数,并且转换成功, *endptr 将被 设置为指向第一个未转换字符的指针。如果 endptr NULL ,则不使用它。
    • base :用于指定转换的基数。它可以是 2 到 36 之间的值,或者是特殊值 0。如果 base 是 0,则函数会根据字符串的前缀(如 “0x” 或 “0X” 表示十六进制,“0” 表示八进制,否则默 认为十进制)来自动确定基数。
  • strtoul

    unsigned long strtoul(const char *str, char **endptr, int base);
    

    将字符串转换为无符号长整型数。

  • strtod

    double strtod(const char *str, char **endptr);
    

    将字符串转换为双精度浮点数。

  • atoi

    int atoi(const char *str);
    

    将字符串转换为整型数(不推荐使用,建议使用strtol)。

  • atol

    long atol(const char *str);
    

    将字符串转换为整型数(不推荐使用,建议使用strtol)。

  • atof

    long atof(const char *str);
    

    将字符串转换为整型数(不推荐使用,建议使用strtol)。

案例:

#include <stdio.h>
#include <stdlib.h>

int main(int argc,char *argv[])
{
    printf("%lo,%ld,%lx\n",strtol("12",NULL,8),strtol("12",NULL,10),strtol("12",NULL,16));
    printf("%lo,%ld,%lx\n",strtol("012",NULL,0),strtol("12",NULL,10),strtol("0x12",NULL,0));
    int a = 10;
    printf("%p,%lx\n",&a,&a);
    return 0;
}

main()
{
    int a=2,b=-1,c=2;
    if(a<b)
        if(b<0) c=0;
    else c+=1;
    printf("%d\n",c);
}

关于单字符的输入:

  • scanf(“%c”,…)
  • getchar();

关于单字符的输出:

  • printf(“%c”,…);
  • putchar();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值