C语言学习第006课——数组、字符数组、字符串

数组的定义和使用

数组的定义方式:

数据类型  数组名[元素个数] = {1,2,3};
数据类型  数组名[] = {1,2,3....};    这样写可以不用限定有多少个元素

数组下标:数组名[下标] 数组下标从0开始 到(数组个数-1)
数组在内存中的存储方式: 是连续的一片内存空间 例如 :

int array[3] = {1,2,3};

第一个元素内存地址为0x00 第二个元素内存地址为0x04 0x08这样
数组名不能被赋值,因为数组名是一个地址常量,指向数组首地址的常量, 例如 打印array的地址和打印array[0]的地址,结果是一样的
数组占用内存大小:

sizeof(array);

数组中元素占用内存大小

sizeof(array[0]);

数组中元素的个数就等于

sizeof(array)/sizeof(array[0]);
这样遇到第二种定义数组方式的时候,就可以直接根据数组实际长度来进行遍历元素

数组的初始化

int arr[5] = {1,2,3,4,5};  遍历打印元素为 1,2,3,4,5
int arr[10] = {1,2,3,4,5}; 遍历打印元素为 1,2,3,4,5,0,0,0,0,0
int arr[10] = {1}          遍历打印元素为 1,0,0,0,0,0,0,0,0,0
int arr[10];  只声明了内存空间,但是没有赋值, 遍历元素打印为10个乱码
如果上一行加一个   arr[0] = 1;  遍历元素打印为1,9个乱码 这种定义方式一般用作从键盘获取数据赋值给数组元素

定义数组的时候, 数组个数必须是常量或者常量表达式 例如

 int a = 10;  
 int arr[a];

这样写是不对的 数组个数必须使用固定的数,而不能使用变量
定义数组必须预先知道数组大小。如果是动态数组的话,考虑开辟堆空间
数组越界:
C语言中,数据是直接存储在内存中的,如果出现数组越界的情况,默认是不会报错的,他会一直跟着越界的下标去读取下一部分内存的值,但是值可能是乱码

二维数组

二维数组的大小:

**sizeof(数据类型)

二维数组名指向的是二维数组第一行第一列的地址
二维数组第一行指向的也是第一行第一列的地址
示例:

int arr[2][3] = {{1,2,3},{4,5,6}};
printf("%p\n",arr);
printf("%p\n",arr[0]);
printf("%p\n",&arr[0][0]);       
三行打印的值都是一样的

二维数组的初始化:

int arr[2][3] = {1,2,3,4,5,6};   这样写也可以,但是不建议这样写,阅读性不强
int arr[][3] = {1,2,3,4,5,6};    这样写也可以,虽然不知道有几行,但是知道有几列,根据元素个数,行数是一个可变的值,元素列数不够的,后面补0
如果连3(列数)都不写,就不行了,记住,不管是二维数组还是多维数组,离数组名最近的那个参数是可以省略的,其他的参数不可以省略
int arr[2][3] = {0};  二维数组的值全部赋值为0

字符数组和字符串

定义字符数组:

char arr[5] = {'h','e','l','l','o'};

定义字符

char c = 'a';

定义字符串

字符串的结束标志为'\0'
char * arr = "hello";
char arr[] = "hello";
char arr[] = {'h'','e','l','l','o','\0'};

如果字符数组结尾是一个\0可以把它看成是一个字符串,反过来说,字符串是字符数组的一个特例,因为他的最后一位是\0
数字0等同于\0,但是不等同于“0”
示例:

char arr[6] = {'h','e','l','l','o'};      多一位默认补0  打印结果hello
char arr[6] = {'h','e','l','l','o','\0'}; 打印结果hello
char arr[5] = {'h','e','l','l','o'};      打印结果 出现乱码

通过键盘获取字符串

char ch[10];   定义字符数组存储字符串
scanf("%s",ch);为什么第二个参数ch不用取地址符呢?因为ch是一个字符数组名,他本身就是一个地址,scanf输入默认以空格分隔
printf("%s",ch);
如果输入helloworld 程序会报错,因为ch定义了10个长度,而且又是以%s接收的,他要预留一个位置存放'\0'
如果输入helloworl  打印正常
如果输入hello wor  会打印hello  因为scanf会将空格认为输入结束
扩展:为了防止输入的字符数大于字符数组长度,可以这样写:scanf("%9s",ch); 这样不管键盘输入多少个字符,只取前9位字符

字符串拼接

char ch1[] = "hello";
char ch2[] = "world";
char ch3[20];
int i = 0;
int j = 0;
while(ch1[i] != '\0'){
	ch3[i] = ch1[i];
	i++;
} 
while(ch2[j] != '\0'){
	ch3[i+j] = ch2[j];
	j++;
}
ch3[i+j] = 0;
printf("%s",ch3);

字符串的输入输出

  • gets()
    从标准输入读入字符,并保存到指定的内存空间,直到出现换行或者读到文件结尾为止

    char ch[100];
    gets(ch);
    printf("%s",ch);
    

    gets(str)与scanf("%s",str)的区别:

    gets(str)允许输入的字符串含有空格
    scanf("%s",str)不允许含有空格
    

    注意:由于scanf和gets无法知道字符串s大小,必须遇到换行符或者读到文件结尾为止才接收输入,因此容易导致字符数组越界的情况
    scanf通过正则表达式,也可以接收空格

    scanf("%{^\n}",ch);
    正则表达式表示接收非回车符的所有字符
    
  • fgets()

    #include <stdio.h>
    char *fgets(char *s,int size,FILE *stream);
    参数:s        字符串
         size     指定最大读取字符串的长度(size-1)
         stream   文件指针,如果读键盘输入的字符串,固定写为stdin
    返回值   成功:读取到的字符串
            失败: NULL
    

    该函数表示从stream指定的文件内读入字符,保存到s指定的内存空间,直到出现换行字符,读到文件结尾,或是已读了size-1个字符为止,最后会自动加上‘\0’作为字符串结束
    fgets()和scanf()和gets()的区别:
           fgets()在读取一个用户通过键盘输入的字符串的时候,同时把用户输入的回车也作为字符串的一部分,而通过scanf和gets输入字符串的时候不包含结尾的“\n”,但通过fgets结尾多了个“\n”,fgets()函数是安全的,不存在缓冲区溢出的情况
    fgets获取字符串少于元素个数会有\n,大于或者等于元素个数的,没有\n
    例如:

    char ch[10];
    fgets(ch,sizeof(ch),stdin);
    printf("%s",ch);
    如果从键盘输入的是 hello   结果会输出hello并且光标换到下一行
    如果从键盘输入的是 helloworld ,结果会输出helloworl光标在当前行,并不会换到下一行
    

    所以说fgets也是有缺点的,他会把\n当做字符的一部分输入

  • puts()

    #include <stdio.h>
    int puts(const char *s);
    功能:标准设备输出字符串,在输出后自动输出一个'\n'
    参数:s:字符串首地址
    返回值:成功:非负数
    失败:-1
    

    puts自带换行,而且内部也是以’\0’作为标识来进行打印的
    换行操作最简单的写法:puts("");

  • fputs()

    #include <stdio.h>
    int fputs(const char *s,FILE *stream);
    从stream指定的文件内输出字符,如果是控制台输出字符串,固定写为stdout
    

    示例:

    char ch[] = "hello world";
    fputs(ch,stdout);
    

    fputs()不会自带换行符

字符串的长度

#include <string.h>
size_t strlen(const char *s);
计算指定字符串s的长度,不包含结束符'\0',也就是计算字符数组的真实长度
size_t      无符号整形   使用%d占位符打印就可以

举例:

char ch[100] = "hello world";
printf("数组大小:%d",sizeof(ch));  100
printf("数组大小:%d",strlen(ch));  11
                                                  
char ch[] = "hello world";
printf("数组大小:%d",sizeof(ch));  12
printf("数组大小:%d",strlen(ch));  11
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值