【408专项篇】C语言笔记-第五章(一维数组与字符数组)

news2025/1/12 16:11:03

第五章:一维数组与字符数组

第一节:一维数组

1. 数组的定义

C语言提供的数组,通过一个符号来访问多个元素。

特点:

  1. 具有相同的数据类型。
  2. 使用过程中需要保留原始数据。

数组是构造数据类型。所谓数组,是指一组具有相同数据类型的数据的有序集合。

格式:

类型说明符 数组名[常量表达式];

例如:int a[10];

声明数组时要遵循以下规则:

  1. 数组名的命名规则和变量名相同,即遵循标识符命名规则。
  2. 在定义数组时,需要指定数组中元素的个数,方括号中的常量表达式用来表示元素的个数,即数组长度。
  3. 常量表达式中可以包含常量和符号常量,但不能包含变量。即不允许对数组大小的做动态定义。

2. 一维数组在内存中的存储

数组元素下标从0开始。

一维数组初始化方法:

  1. 在定义数组时对数组元素赋初值。int a[10]={0,1,2,3,4,5,6,7,8,9};
  2. 可以只给一部分元素赋值。int a[10]={0,1,2,3,4,};表示只给前5个元素赋初值,后5个元素的值为0
  3. 如果要使一个数组中的全部元素值为0,可以写成:int a[10]={0,0,0,0,0,0,0,0,0,0};或int a[10]={0};
  4. 在对全部数组元素赋初始值时,由于数组的个数已经确定,因此可以不指定数组的长度。int a[]={1,2,3,4,5};

第二节:数组访问越界与传递

1. 数组的访问越界

#include <stdio.h>

int main() {
    int a[5]={1,2,3,4,5};
    int j=20;
    int i=30;
    a[5]=6;  // 越界访问
    a[6]=7;  // 越界访问导致其他变量值发生变化,异常
    printf("i=%d\n",i);  // i发生变化
    printf("j=%d\n",j);
    return 0;
}
F:\Computer\Project\practice\5\5.1-transboundary\cmake-build-debug\5_1_transboundary.exe
i=7
j=20

进程已结束,退出代码为 0

解析:a[5],a[6]属于越界访问。在内存中,读取到的变量值是紧挨在一起的,如果越界,就会导致其他变量的值被修改。

需要注意的是,编译器并不检查程序对数组下标的引用是否在合法范围内。好处是效率更高,坏处是无法检测出无效的下标引用。需要做好检查

2. 数组的传递

一维数组在传递时,其长度是传递不过去的,所以我们通过借助另外一个参数len来传递数组中的元素个数。

#include <stdio.h>

void print(int b[],int len){  // 子函数需要两个形式参数
    int i;
    for (int i = 0; i < len; i++) {
        printf("%3d",b[i]);
    }
    b[4]=20;
    printf("\n");
}

int main() {
    int a[5]={1,2,3,4,5};
    printf("before a[4]=%d\n",a[4]);
    print(a,5);  // 5是数组a的长度
    printf("after a[4]=%d\n",a[4]);  // a[4]的值已被修改
    return 0;
}
F:\Computer\Project\practice\5\5.2-transmit\cmake-build-debug\5_2_transmit.exe
before a[4]=5
  1  2  3  4  5
after a[4]=20

进程已结束,退出代码为 0

解析:实际数组名中存储的数组的首地址,在调用函数时,试将数组的首地址给了变量b(指针类型),print函数对数组的修改,同等于main函数中对数组的修改。另外通过len将数组长度传递给了函数。

第三节:字符数组与scanf读取字符串

1. 字符数组初始化及传递

字符数组定义:
例如:char c[10];

字符数组初始化和一维数组类似:

char c[10]={‘I’,‘a’,‘m’,‘h’,‘a’,‘p’,‘p’,‘y’};

或者:

c[0]=‘I’;c[1]=‘a’;c[2]=‘m’;…

因为字符数组一般用来存取字符串,所以通常采用的初始化方法是 char c[10]=“hello”。

字符数组存储的字符串长度必须比字符数组定义长度少1个字节,例如:char c[10]最长存储9个字节,剩余的1个字符用来存储’\0’。

#include <stdio.h>

int main() {
    char c[5]={'h','e','l','l','o'};  // 5个字符,定义长度是5,会出现乱码,因为字符没有结束符。最少要定义长度为6
    char d[5]="how";   // 3个字符,定义长度为5,不会出现乱码
    printf("%s\n",c);
    printf("%s\n",d);
    return 0;
}
F:\Computer\Project\practice\5\5.3-char\cmake-build-debug\5_3_char.exe
hello?
how

进程已结束,退出代码为 0

字符数组通过结尾标识’\0’来判断是否结尾。一维数组没有标识,所以需要传递长度,而字符数组不需要传递长度

#include <stdio.h>

void print(char c[]){
    int i=0;
    while (c[i]){
        printf("%c",c[i]);
        i++;
    }
}

int main() {
    char c[5]={'h','e','l','l','o'};  // 5个字符,定义长度是5,会出现乱码,因为字符没有结束符。最少要定义长度为6
    char d[5]="how";   // 3个字符,定义长度为5,不会出现乱码
    printf("%s\n",c);  // 使用%s直接输出字符串
    printf("%s\n",d);
//    printf("================\n");
//    printf("%x\n",*c);  用于打印内存信息
//    printf("%x\n",*(c+1));
//    printf("%x\n",*(c+2));
//    printf("%x\n",*(c+3));
//    printf("%x\n",*(c+4));
//    printf("%x\n",*(c+5));
//    printf("%x\n",*(c+6));
//    printf("%x\n",*(c+7));
    print(d);
    return 0;
}
F:\Computer\Project\practice\5\5.3-char\cmake-build-debug\5_3_char.exe
hello?q
how
how
进程已结束,退出代码为 0

2. scanf读取字符串

scanf读取字符串使用%s

#include <stdio.h>

int main() {
    char c[10];
    char d[10];
    scanf("%s",c);
    printf("%s\n",c);
    scanf("%s%s",c,d);
    printf("c=%s,d=%s\n",c,d);
    return 0;
}
F:\Computer\Project\practice\5\5.3-scarry_char\cmake-build-debug\5_3_scarry_char.exe
hello
hello
are you
c=are,d=you

进程已结束,退出代码为 0

解析:scanf通过%s读取字符串,对c和d分别输入"are"和"you"(中间加一个空格),scanf在使用%s读取字符串时,会忽略空格和回车,这一点和%d和%f类似

第四节:gets、puts、str系列讲解

1. gets函数与puts函数

gets函数类似于scanf函数,用于读取标准输入。区别是scanf遇到空格就认为读取结束,而gets不会,所以某些场景下需要使用gets函数。

gets函数读取字符并把它们加载到str(字符串)中,遇到’\n’才认为读取结束,但不会存储’\n’,而是存储成空字符’\0’。

puts函数类似于printf函数,用于输出标准输出。

puts函数把str(字符串)写入标准输出。并打印到屏幕上,同时打印换行。相对于printf函数,puts只能用于输出字符串,同时多打印一个换行符,等价于printf{“%s\n”,c};

#include <stdio.h>

int main() {
    char c[20];
    gets(c);   // 相当于scanf
    puts(c);   // 相当于printf
    return 0;
}
F:\Computer\Project\practice\5\5.4-gets_puts\cmake-build-debug\5_4_gets_puts.exe
how are you
how are you

进程已结束,退出代码为 0

2. str系列字符串操作函数

strlen:用于统计字符串长度。

strcpy:用于将某个字符串复制到字符数组中。

strcmp:用于比较两个字符串的大小。

strcat:用于将两个字符串连接到一起。

str系列操作函数需要引入标准输入流#include <string.h>

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

int mystrlen(char c[]){
    int i=0;
    while (c[i]){
        i++;
    }
    return i;
}

int main() {
    int len;
    char c[20];
    char d[100]="world";
    gets(c);  // 给c输入hello
    puts(c);
    len= strlen(c);
    printf("len=%d\n",len);  // 打印c的长度
    len=mystrlen(c);
    printf("mylen=%d\n",len);
    printf("%s\n",strcat(c,d));  // 将d拼接在c的后面,并打印
    printf("%s\n",strcpy(d,c));  // 将c的值赋给d,并打印
    puts(d);  // 打印此刻d的值
    printf("c?d %d\n", strcmp(c,d));  // 比较c和d的大小,并打印。
    return 0;
}
F:\Computer\Project\practice\5\5.4-str\cmake-build-debug\5_4_str.exe
hello
hello
len=5
mylen=5
helloworld
helloworld
helloworld
c?d 0

进程已结束,退出代码为 0

解析:对于赋值和拼接的场景,目标数组一定要大于字符串大小,即sizeof(d)>strlen©,否则会造成访问越界。

比较大小方法:将每个字母转换成ASCII码值,从前到后依次比较。如果相等,则返回0。如果前边比后边大,返回1。如果前边比后边小,返回-1。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/24728.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深入理解Python生成器和yield

深入理解Python生成器和yield 我在《Python性能优化指南–让你的Python代码快x3倍的秘诀》中有提到&#xff0c;在处理大文件或大数据集时用生成器可以提高性能。很多朋友会问&#xff1a;“为什么用生成器就能提升性能呢&#xff1f;”。今天&#xff0c;我就带大家深入看一…

Web2 vs. Web3,社交工具的发展会有什么变化?

社交&#xff0c;是不同主体传递、反馈社会信息的主要方式之一。从古代的飞鸽传书、近代的书信往来&#xff0c;到现代大家手机里都必不可少的社交 APP&#xff0c;人们对于社交的需求和实现方式都在不断更新和变化。 当前&#xff0c;Web2 社交赛道已经非常成熟。为吸引更多流…

前端文件流相关

XMLHttpRequest // XMLHttpRequest对象用于与服务器交互 // XMLHttpRequest可以在不刷新页面的情况下请求特定URL, 获取数据 // XMLHttpRequest属性responseType是一个枚举字符串值, 用于指定响应中包含的数据类型 // 如果将 responseType的值设置为空字符串, 则使用 text 作为…

Linux网络编程基础

Linux网络编程基础一、基础概念的介绍1.1 网卡的介绍1.2 mac地址 六个字节 48位1.3 ip地址 32位 四个字节 ipv41.4 端口二、网络模型2.1 OSI七层模型2.2 TCP/IP模型2.3 协议2.4 网络通信过程2.4 arp协议2.5 网络设计模式一、基础概念的介绍 1.1 网卡的介绍 1.2 mac地址 六个字…

开源轻量堡垒机——Teleport的安装配置和使用

一、堡垒机简介 1.1、现状 目前随着信息化的发展&#xff0c;越来越多的企业开始有更多的服务器、业务资源&#xff0c;有更多样化的员工&#xff0c;拥有更多的账号&#xff1b;导致访问混乱化&#xff0c;越权访问难以规范&#xff1b;甚至恶意命令攻击事件&#xff08;如删…

【数据结构】带头节点双向循环链表

目录 顺序表和链表的区别 带头双向循环链表分析 带头双向循环链表结构&#xff1a; 创建一个节点 哨兵位头节点 打印链表中的值 在pos前插入 删除pos位置的节点 尾插 尾删 头插&#xff1a; 头删 链表元素查找 总代码 List.h文件 List.c文件 test.c文件 顺序表和…

科技云报道:历经四年,RPA走向同质化?

科技云报道原创。 经过多年发展&#xff0c;全球RPA市场已经初具规模。 据Transparency Market Research研究预测&#xff0c;预计到2024年&#xff0c;全球RPA市场规模将达到50亿美元&#xff0c;实现61.3%的年复合增长率。 RPA在亚洲市场起步晚于欧美市场&#xff0c;但从2…

SpringCloud系列(二)Ribbon 负载均衡的原理及详细流程

关于负载均衡这个概念在上一篇文章中有所提到&#xff0c;在消费者远程调用之前有一个重要的环节就是负载均衡&#xff0c;那么为什么要进行负载均衡呢&#xff1f;其原理及实现流程如何&#xff1f;   其实 Ribbon 负载均衡可以认为是一种策略&#xff0c;也可以说是某种规则…

SpringBoot+Vue项目实现身体健康诊疗系统

文末获取源码 开发语言&#xff1a;Java 使用框架&#xff1a;spring boot 前端技术&#xff1a;JavaScript、Vue.js 、css3 开发工具&#xff1a;IDEA/MyEclipse/Eclipse、Visual Studio Code 数据库&#xff1a;MySQL 5.7/8.0 数据库管理工具&#xff1a;phpstudy/Navicat JD…

ajax尚硅谷笔记——跨域请求、axios发送ajax请求、jquery发送ajax请求

去恶补了ajax知识 一、ajax简介 1、ajax全称为Asynchronous JavaScript And XML&#xff0c;就是异步的JS 和XML 2、通过AJAX可以再浏览器中向服务器发送异步请求&#xff0c;最大的优势&#xff1a;无刷新获取数据 3、ajax不是新的编程语言&#xff0c;而是一种将现有的标准…

《Linux内核设计与实现》读书笔记

《Linux内核设计与实现》读书笔记第三章 进程管理第四章 进程调度第五章 系统调用第六章 内核数据结构第七章 中断和中断处理第八章 下半部和推后执行的工作第九章 内核同步介绍第十章 内核同步方法第十一章 定时器和时间管理第十二章 内存管理第十三章 虚拟文件系统第十四章 块…

Java:2022年全球使用的15种最流行的Java应用

到今年为止&#xff0c;Java已经有25年的历史了&#xff0c;尽管引入了许多更新、更华丽的语言和工具&#xff0c;但它仍然是当今最流行的编程语言之一。这们老语言一直在蹒跚前行&#xff0c;享受着当今众多程序员和开发人员的爱。 Java有许多优势&#xff0c;再加上它的广泛使…

transformer论文及其变种

文章目录transformer模型细节slf-attn & multi-head attnabs positionwhy slf-attntransformer-XLInformer细节probSparse slf-attnLongformer细节GPT-generative pre-train模型结构下游任务&#xff1a;fine-tuningtransformer motivation&#xff1a;序列映射的任务&…

高速串行信号串接电容放在发送端还是接收端

在设计一些高速的串行信号&#xff0c;比如PCIE&#xff0c;STATA&#xff0c;USB3.0等&#xff0c;在差分信号线上面常常都会串接一个电容 这个电容主要有如下几个方面的作用&#xff1a; 1.滤除信号的直流分量&#xff0c;使信号关于0电平对称&#xff1b; 因为很多高速信号…

持续集成环境-maven、tomcat安装和配置

在Jenkins 集成环境中&#xff0c;用Maven编译、打包项目 壹&#xff0c;安装Maven 安装在jenkins服务器上 官方下载地址 上传安装包 解压 &#xff1a; tar -zxvf apache-maven-3.6.2-bin.tar.gzmkdir -p /opt/maven #创建目录 mv apache-maven-3.6.2/* /opt/maven #移…

Vue3中v-if与v-for、多事件处理器即案件修饰符、$attrs、$root和$parent

文章目录1. v-if与v-for及动态属性ref的使用2. 多事件处理器及按键修饰符3. $attrs包含class和style4. \$root和$parent1. v-if与v-for及动态属性ref的使用 在 vue3 中&#xff0c;当 v-if 与 v-for 一起使用时&#xff0c;v-if 具有比 v-for 更高的优先级。 下面是 v-for 结…

ubuntu20.04搭建janus服务器

目录 一、安装依赖项 二、编译janus v1.1.0 三、生成ssl证书 四、编译配置nginx 五、编译turnserver 六、配置janus文件 七、编译janus报错记录 参考资料&#xff1a; 环境是ubuntu20.04 使用最新的janus v1.1.0代码。 一、安装依赖项 sudo apt-get install aptitude…

Linux搭建Rabbitmq集群

1.1 添加其他用户 133、134、135 因为 guest 用户只能在本机访问&#xff0c;添加一个 admin 用户&#xff0c;密码也是 admin ./rabbitmqctl add_user admin admin ./rabbitmqctl set_user_tags admin administrator ./rabbitmqctl set_permissions -p / admin “." &qu…

嵌入式软件设计之美-以实际项目应用MVC框架与状态模式(下)

上节我们分享了MVC框架、状态模式组合在实际开发中的应用&#xff0c;它能够让我们的软件设计流程更加的清晰、易于维护&#xff1a; 嵌入式软件设计之美-以实际项目应用MVC框架与状态模式(上) 那么这一节我们就直接开门见山&#xff0c;从接下来的这个开源项目分享开始&…

An2023(Animate2023)中文版软件下载「附带安装教程」

animate2023版本已经更新&#xff0c;此次的最新版本中&#xff0c;拥有大量的新特性&#xff0c;特别是在继续支持Flash SWF、AIR格式的同时&#xff0c;还会支持HTML5Canvas、WebGL&#xff0c;并能通过可扩展架构去支持包括SVG在内的几乎任何动画格式&#xff0c;更新推出了…