从零开始的嵌入式生活:一维数组详解(2)

一、字符数组定义

用来存放字符的数组称为字符数组,例如:

char a[10];  //定义一维字符数组 ,数组里面元素的值是未知的
char b[10]={'c', 'p', 'r', 'o'};//给部分一维字符数组赋值,未赋值数组系统,默认为'\0'
char c[5] = {'h', 'e', 'l', 'l', 'o'};

字符数组实际上是一系列字符的集合,也就是字符串(String)。在C语言中,没有专门的字符串变量,没有string类型,通常就用一个字符数组来存放一个字符串。

C语言规定,可以将字符串直接赋值给字符数组,例如:

char a[20] = {"C progarm"};//给一维字符数组赋值字符串
char d[10] = "hello";    //给一维字符数组赋值字符串

数组第 0 个元素为'C',第 1 个元素为' ',第 2 个元素为'p',后面的元素以此类推。

这里需要留意,字符数组只有在定义时才能将整个字符串一次性地赋值给它,一旦定义完了,就只能一个字符一个字符地赋值了。请看下面的例子:

char str[7];

str = "adc123";  //这是错误的

//正确
    str[0] = 'a';
    str[1] = 'b';
    str[2] = 'c';
    str[3] = '1';
    str[4] = '2';
    str[5] = '3';

二、字符串结束标志

字符串是一系列连续的字符的组合,要想在内存中定位一个字符串,除了要知道它的开头,还要知道它的结尾。找到字符串的开头很容易,知道它的名字(字符数组名或者字符串名)就可以;然而,如何找到字符串的结尾呢?C语言的解决方案有点奇妙,或者说有点奇葩。

在C语言中,字符串总是以'\0'作为结尾,所以'\0'也被称为字符串结束标志,或者字符串结束符。

'\0'是 ASCII 码表中的第 0 个字符,英文称为 NUL,中文称为“空字符”。该字符既不能显示,也没有控制功能,输出该字符不会有任何效果,它在C语言中唯一的作用就是作为字符串结束标志。

C语言在处理字符串时,会从前往后逐个扫描字符,一旦遇到'\0'就认为到达了字符串的末尾,就结束处理。'\0'至关重要,没有'\0'就意味着永远也到达不了字符串的结尾。

char str[7] = "adc123";

由" "包围的字符串会自动在末尾添加'\0'。例如,"abc123"从表面看起来只包含了 6 个字符,其实不然,C语言会在最后隐式地添加一个'\0',这个过程是在后台默默地进行的,所以我们感受不到。

下面的代码演示了"C program"在内存中的存储情形:

#include <stdio.h>

int main(void)
{
    int i;
    char str[15] = "C program";  //用双引号括起来字符,就是字符"C"  'C'

    for(i=0; i<15; i++)
    {
        printf("%d ", str[i]);

    }

    printf("\n");

    return 0;
}

输出:

输出
C ' ' p   r    o   g  r   a   m  '\0'
67 32 112 114 111 103 114 97 109  0   0  0  0 0 0

需要注意的是,逐个字符地给数组赋值并不会自动添加'\0',例如:

char str[] = {'a', 'b', 'c'}

数组 str 的长度为 3,而不是 4,因为最后没有'\0'。

当用字符数组存储字符串时,要特别注意'\0',要为'\0'留个位置;这意味着,字符数组的长度至少要比字符串的长度大 1。

三、字符串长度

所谓字符串长度,就是字符串包含了多少个字符(不包括最后的结束符'\0')。例如"abc"的长度是 3,而不是 4。

在C语言中,我们使用string.h头文件中的 strlen() 函数来求字符串的长度,它的用法为:

length strlen(strname);

strname 是字符串的名字,或者字符数组的名字;length 是使用 strlen() 后得到的字符串长度,是一个整数。

例子:

#include <stdio.h>
#include <string.h>  //这个头文件包含strlen函数声明

int main(void)
{
    int len;
    char str[30] = "www.baidu.com";

    len = strlen(str);  //这个是系统提供的函数,要用到头文件 string.h

    printf("len:%d\n", len);

    return 0;
}

运行结果:

len:13

四、数组长度

数组长度是指数组所有内存的大小,按字节来计算,通过C语言关键字sizeof

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

int main(void)
{
    int len;
    int arr[4] = {1, 2, 3, 4};
    char str[30] = "www.baidu.com";

    printf("数组arr所占空间大小:%d\n", sizeof(arr));
    printf("数组str所占空间大小:%d\n", sizeof(str));

    return 0;
}

输出:

数组arr所占空间大小:16
数组str所占空间大小:30

记住:数组长度公式: 元素个数*数据类型所占空间大小

五、字符串的输入和输出

在C语言中,有两个函数可以让用户从键盘上输入字符串,它们分别是:

  • scanf():通过格式控制符%s输入字符串。除了字符串,scanf() 还能输入其他类型的数据。
  • gets():直接输入字符串,并且只能输入字符串。

但是,scanf() 和 gets() 是有区别的:

  • scanf() 读取字符串时以空格为分隔,遇到空格就认为当前字符串结束了,所以无法读取含有空格的字符串。
  • gets() 认为空格也是字符串的一部分,只有遇到回车键时才认为字符串输入结束,所以,不管输入了多少个空格,只要不按下回车键,对 gets() 来说就是一个完整的字符串。换句话说,gets() 用来读取一整行字符串。

在C语言中,有两个函数可以在控制台(显示器)上输出字符串,它们分别是:

  • puts():输出字符串并自动换行,该函数只能输出字符串。
  • printf():通过格式控制符%s输出字符串,不能自动换行。除了字符串,printf() 还能输出其他类型的数据。
#include <stdio.h>
#include <string.h>

int main(void)
{

    char str1[30] = {0};
    char str2[30] = {0};
    char str3[30] = {0};

    printf("gets请输入字符串:");
    gets(str1);

    printf("scanf请输入字符串:");
    scanf("%s", str2);  //数组名字就是地址
    scanf("%s", str3);

    printf("str1:%s\n", str1);
    printf("str2:%s\n", str2);
    puts(str3);


    return 0;
}

 结果:

gets请输入字符串:C Program
scanf请输入字符串:PHP JAVA C
str1:C Program
str2:PHP
str3:JAVA

 

第一次输入的字符串被 gets() 全部读取,并存入 str1 中。第二次输入的字符串,前半部分被第一个 scanf() 读取并存入 str2 中,后半部分被第二个 scanf() 读取并存入 str3 中。

注意,scanf() 在读取数据时需要的是数据的地址,这一点是恒定不变的,所以对于 int、char、float 等类型的变量都要在前边添加&以获取它们的地址。但是在本段代码中,我们只给出了字符串的名字,却没有在前边添加&,这是为什么呢?因为字符串名字或者数组名字在使用的过程中一般都会转换为地址,所以再添加&就是多此一举,甚至会导致错误了。

就目前笔者写到的知识而言,int、char、float 等类型的变量用于 scanf() 时都要在前面添加&,而数组或者字符串用于 scanf() 时不用添加&,它们本身就会转换为地址。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值