C语言数组之字符数组

C语言

主要内容

  • 数组
    • 字符数组

数组

字符数组

概念

元素类型为char字符型的数组,字符数组往往是用来存储字符串数组的。需要注意的一点是,我们C语言中的字符是字节字符。

字节字符:也就是1个字符占一个字节,在C语言中,我们使用char表示字节。

测试题:

char a = 'A';   // 正确
char b = '1';   // 正确
char c = 65;    // 正确, char支持两种赋值形式,一种是字符,一种是数值,如果是数值表示ASCII码
char d = "A";   // 错误,char字符不能使用双引号。
char e = '卜';  // 错误,中文一个字符超过了一个char

C语言支持字符串常量,不支持字符串变量

语法:
char 数组名 [容量];
char 数组名 [行容量][列容量];

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

注意:

​ 如果我们的char数组初始化的时候,没有完全初始化值的时候,空出来的地方使用\0进行填充。大家要注意,这里的\0只是起到占位的作用,我们是无法通过printf进行输出的。

比如:

char c[8] = {'h','e','l','l','o'}; // 等价于
char c[8] = {'h','e','l','l','o','\0','\0','\0'};
案例

案例1:

  • 需求:输出一个字符序列(I LOVE YOU)

  • 代码:

    #include <stdio.h>
    
    int main()
    {
        // 创建一个数组,用来存储 I LOVE YOU ASCI中32对应的就是空格' '
        char arr[10] = {'I',' ','L','O','V','E',32,'Y','O','U'};
        
        // 使用for循环遍历数组
        for(int i = 0; i < sizeof(arr)/sizeof(char); i++)
        {
        	printf("%c",arr[i]);
        }
        printf("\n");
        
        return 0;
    }
    

案例2:

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

  • 代码:

    #include <stdio.h>
    
    int main()
    {
        // 准备数据
        char arr[5][5] = {
            {' ',' ','*',' ',' '},
            {' ','*','*','*',' '},
            {'*','*','*','*','*'},
            {' ','*','*','*',' '},
            {' ',' ','*',' ',' '}
        };
        // 遍历数组
        for (int i = 0;i < sizeof(arr)/sizeof(arr[0]); i++)
        {
            for (int j = 0; j < sizeof(arr[i])/sizeof(char); j++)
            {
            	printf("%c",arr[i][j]);
            }
            printf("\n");
        }
        printf("\n");
        
        return 0;
    }
    

注意:

① 如果定义时,不初始化,元素值不确定

char arr1[2]; // 此时属于未初始化,元素的值是不确定的(随机值),大概率是\0。也有可能是其他
值。
char arr2[5] = {'a','b','c'}; // 此时属于不完全初始化,未初始化的元素使用\0进行填充

② 如果提供的字符个数大于数组长度,则按照语法错误处理;如果字符个数小于数组长度,后面的元素自动为空字符(\0)

③ 如果提供的字符个数与数组长度相同,可以省略数组长度,系统会自动确定元素个数,适合字符较多时。

字符串结束标志
说明
  • C语言规定,字符串以字符\0作为结束标志。
  • 编译系统对字符串常量自动加一个\0作为结束标志。
  • 程序中往往通过判断\0来检测字符串是否结束。
  • \0的ASCII码是0,不是一个可显示的字符,是“空操作符”,它什么都不做,不会增加有效字符,仅是一个工程判别的标志。
char c[] = {'h','i'};       // hi
char c[] = {'h','i','\0'};  // hi
char c[] = "hello";         // 实际等价于 hello\0
// \0(空字符),ASCII码是0
// 0 , ASCII码是48
// 空格,ASCII码是32
字符数组的多样表示

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

#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("%s\n%s\n%s\n",s1,s2,s3);
    
    return 0;
}

注意:

  • 字符串的长度与字符数组的长度不一定相同。
  • 利用字符串常量可以对字符数组进行初始化,但不能用字符串常量对字符数组赋值。
// 正确演示:利用字符串常量给字符数组初始化
char arr1[6] = "hello";

// 错误演示:用字符串常量为字符数组赋值
char arr2[6];
arr2 = "hello";
字符串的基础操作

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

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

字符串输入
scanf

语法:

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

注意:数组名对应的数组只能是char类型

案例:

#include <stdio.h>

int main(int argc,char *argv[])
{
    // 创建一个数组,用来存放人的名字
    char name[20];
    
    printf("请输入您的名字:\n");
    scanf("%s",name);// scanf第二个参数需要传递变量地址,如果是数组,数组名就代表数组的首地址,因为
    数组本身是没有空间的,其空间就是元素空间
    printf("您的姓名是%s\n",name);
    return 0;
}

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

fgets

语法:

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

功能:

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

说明:

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

案例:

#include <stdio.h>

int main(int argc,char *argv[])
{
	// 创建一个数组,用来存放人的名字
    char name[20];
    
    printf("请输入您的名字:\n");
    // fgets和scanf只能二选一
    fgets(name,sizeof(name)/sizeof(name[0]),stdin);
    printf("您的姓名是%s\n",name);
    return 0;
}

注意:

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

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

​ ③ 经过对比,我们发现,在字符串输入中,fgets和scanf相比,fgets友好一些

gets 危险的

语法:

gets(数组名);

功能:

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

说明:

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

案例:

#include <stdio.h>

int main(int argc,char *argv[])
{
    // 创建一个数组,用来存放人的名字
    char name[20];
    
    printf("请输入您的名字:\n");
    // fgets和scanf只能二选一
    fgets(name,sizeof(name)/sizeof(name[0]),stdin);
    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);// scanf第二个参数需要传递变量地址,如果是数组,数组名就代表数组的首地址,因为数组本身是没有空间的,其空间就是元素空间
    printf("您的姓名是%s\n",name);
    return 0;
}
fputs

语法:

fputs(const char *s,FILE *stream);

功能:

​ 输出一个字符串

说明:

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

案例:

#include <stdio.h>

int main(int argc,char *argv[])
{
    // 创建一个数组,用来存放人的名字
    char name[20];
    
    printf("请输入您的名字:\n");
    // gets、fgets和scanf只能多选一
    gets(name);
    
    // 输出
    fputs(name,stdout);// 标准的输出
    return 0;
}
puts

语法:

puts(const char *s);

功能:

​ 输出一个字符串

说明:

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

案例:

#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将被设置为指向第一个未转换字符的指针。如果 endptrNULL,则不使用它。
    • 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

    double atof(const char *str);
    

    将字符串转换为双精度浮点数(不推荐使用,建议使用 strtod)。

案例:

#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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值