嵌入式第四天:(C语言入门)

目录

什么是数组?

数组:

数组的使用:

数组的初始化:

数组名:

数组案例:

一维数组的最大值:

一维数组的逆置:

数组和指针:

通过指针操作数组元素:

指针数组:

数组名做函数参数:

字符数组与字符串:

字符数组与字符串区别:

字符串的输入输出:

字符指针:

 字符串常用库函数:

strlen:

strcpy:

strcat:

 strcmp:

字符串案例:


什么是数组?

1. 数组是C语言中的一种数据结构,用于存储一组具有相同数据类型的数据。

2. 数组中的每个元素可以通过一个索引(下标)来访问,索引从0开始,最大值为数组长度减1。

数组:
数组的使用:

语法格式:

类型 数组名[元素个数];
int arr[5];

1. 数组名不能与其它变量名相同,同一作用域内是唯一的。

2. 其下标从0开始计算,因此5个元素分别为 arr[0],arr[1],arr[2],arr[3],arr[4]。

#include <stdio.h>

int main() {
    // 定义了一个数组,名字叫a,有10个成员,每个成员都是int类型
    int a[10]; 
    // a[0]…… a[9],没有a[10]
    // 没有a这个变量,a是数组的名字,但不是变量名,它是常量
    a[0] = 0;
    // ……
    a[9] = 9;
    // 数据越界,超出范围,错误
    // a[10] = 10;  // err

    for (int i = 0; i < 10; i++) {
        a[i] = i; // 给数组赋值
    }

    // 遍历数组,并输出每个成员的值
    for (int i = 0; i < 10; i++) {
        printf("%d ", a[i]);
    }
    printf("\n");

    return 0;
}
数组的初始化:

1. 在定义数组的同时进行赋值,称为初始化。

2. 全局数组若不初始化,编译器将其初始化为零。

3. 局部数组若不初始化,内容为随机值。

	int a1[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; // 定义一个数组,同时初始化所有成员变量
	int a2[10] = { 1, 2, 3 }; // 初始化前三个成员,后面所有元素都设置为0
	int a3[10] = { 0 }; // 所有的成员都设置为0

	 // []中不定义元素个数,定义时必须初始化
	int a4[] = { 1, 2, 3, 4, 5 }; // 定义了一个数组,有5个成员
数组名:

数组名是一个地址的常量,代表数组中首元素的地址。

#include <stdio.h>

int main() {
    // 定义一个数组,同时初始化所有成员变量
    int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 

    // 数组名是一个地址的常量,代表数组中首元素的地址
    printf("a = %p\n", a);
    printf("&a[0] = %p\n", &a[0]);

    int n = sizeof(a);     // 数组占用内存的大小,10个int类型,10 * 4  = 40
    int n0 = sizeof(a[0]); // 数组第0个元素占用内存大小,第0个元素为int,4
    int num = n / n0;      // 元素个数
    printf("n = %d, n0 = %d, num = %d\n", n, n0, num);

    return 0;
}
数组案例:
一维数组的最大值:
#include <stdio.h>

int main() {
    // 定义一个数组,同时初始化所有成员变量
    int a[] = {1, -2, 3, -4, 5, -6, 7, -8, -9, 10};

    // 假设第0个元素就是最大值
    int temp = a[0];
    for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++) {
        // 如果有元素比临时的最大值大,就交换值
        if (a[i] > temp) {
            temp = a[i];
        }
    }
    printf("数组中最大值为:%d\n", temp);

    return 0;
}
一维数组的逆置:
#include <stdio.h>

int main() {
    // 定义一个数组,同时初始化所有成员变量
    int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 

    int i = 0;  // 首元素下标
    int j = sizeof(a) / sizeof(a[0]) - 1;   // 尾元素下标
    int temp;

    while (i < j) {
        // 元素交换值
        temp = a[i];
        a[i] = a[j];
        a[j] = temp;
        // 位置移动
        i++;
        j--;
    }

    for (i = 0; i < sizeof(a) / sizeof(a[0]); i++) {
        printf("%d, ", a[i]);
    }

    return 0;
}
数组和指针:
通过指针操作数组元素:

1. 数组名字是数组的首元素地址,但它是一个常量。

2. * 和 [] 效果一样,都是操作指针所指向的内存。

#include <stdio.h>

int main() {
    int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    int i = 0;
    int n = sizeof(a) / sizeof(a[0]);

    for (i = 0; i < n; i++) {
        // * 和 [] 效果一样,都是操作指针所指向的内存
        // printf("%d, ", a[i]);
        printf("%d, ", *(a + i));
    }
    printf("\n");

    // 定义一个指针变量保存a的地址
    int *p = a; 
    for (i = 0; i < n; i++) {
        // printf("%d, ", p[i]);
        printf("%d, ", *(p + i));
    }
    printf("\n");

    return 0;
}
指针数组:

指针数组,它是数组,数组的每个元素都是指针类型。

#include <stdio.h>

int main() {
    // 指针数组
    int *p[3];
    int a = 1;
    int b = 2;
    int c = 3;

    // 指针变量赋值
    p[0] = &a;
    p[1] = &b;
    p[2] = &c;

    for (int i = 0; i < sizeof(p) / sizeof(p[0]); i++) {
        printf("%d, ", *(*(p + i)));
        // printf("%d, ", *(p[i]));
    }
    printf("\n");

    return 0;
}
数组名做函数参数:

数组名做函数参数,函数的形参本质上就是指针。

#include <stdio.h>

// 下面3种写法完全等价
// void print_arr(int a[10], int n)
// void print_arr(int a[], int n)
void print_arr(int *a, int n) {
    int i = 0;
    for (i = 0; i < n; i++) {
        printf("%d, ", a[i]);
    }
    printf("\n");
}

int main() {
    int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    int n = sizeof(a) / sizeof(a[0]);

    // 数组名做函数参数
    print_arr(a, n);

    return 0;
}
字符数组与字符串:
字符数组与字符串区别:

1. C语言中没有字符串这种数据类型,可以通过char的数组来替代。

2. 数字0(和字符 '\0' 等价)结尾的char数组就是一个字符串,字符串是一种特殊的char的数组。

3. 如果char数组没有以数字0结尾,那么就不是一个字符串,只是普通字符数组。

字符串的输入输出:

 由于字符串采用了'\0'标志,字符串的输入输出将变得简单方便。

#include <stdio.h>

int main()
{
    char str[100];

    printf("input string1: ");
    // scanf("%s",str) 默认以空格分隔
    // 可以输入空格
    gets(str);
    printf("output: %s\n", str);

    return 0;
}
字符指针:

1. 字符指针可直接赋值为字符串,保存的实际上是字符串的首地址。

2. 这时候,字符串指针所指向的内存不能修改,指针变量本身可以修改。

#include <stdio.h>

int main() {
    char *p = "hello";  // 和 const char *p = 'hello' 等价,有没有const都一样
    // 指针变量所指向的内存不能修改
    // *p = 'a';    // err
    printf("p = %s\n", p);

    // 指针变量可以修改
    p = "world";
    printf("p = %s\n", p);

    return 0;
}
 字符串常用库函数:
strlen:

作用:

strlen 函数的作用是返回字符串的长度,即字符串中字符的个数,不包括末尾的空字符('\0')。

解释:

在C语言中,字符串是以字符数组的形式存储的,并且以空字符串('\0')作为结束标签。strlen函数通过遍历这个字符数组,直到遇到空字符为止,来计算字符串的长度。

函数原型:

size_t strlen(const char *str);

1. str是一个指向字符数组(字符串)的指针

2. 函数返回一个size_t 类型的值,表示字符串的长度。

示例:

#include <stdio.h>  
#include <string.h>  
  
int main() {  
    char str[] = "Hello, World!";  
    printf("The length of the string is: %zu\n", strlen(str));  
    return 0;  
}

输出:

The length of the string is: 13

 注意事项:

  1. strlen 函数不会检查传入的指针是否为null,所以在使用之前应该确保指针是有效的。
  2. strlen 函数计算的是字符串中字符的个数,不包括末尾的空字符。
  3. 由于 strlen 需要遍历整个字符串来计算长度,所以对于非常长的字符串,它的执行时间可能会相对较长。如果你在处理大量字符串或者对性能有严格要求的情况下,可能需要考虑其他方法来优化字符串长度的计算。
strcpy:

作用:

strcpy 函数的作用是将一个字符串(包括空字符'\0')复制到另一个字符串中,源字符串以空字符'\0'结束,strcpy 会将源字符串的所有字符(直到空字符为止)复制到目标字符串中,并且在目标字符串的末尾添加一个空字符,以表示字符的结束。

解释:

在C语言中,字符串是通过字符数组来表示的。strcpy 函数接受两个参数:一个是指向目标字符串的指针,另一个是指向源字符串的指针。函数将源字符串的内容复制到目标字符串中,覆盖目标字符串的原始内容(如果有的话)。

函数原型:

char *strcpy(char *dest, const char *src);

 1. dest 是一个指向目标字符数组的指针,用于存储复制的字符串。

 2. src 是一个指向源字符数组的指针,既要复制的字符串。 

 3. 函数返回一个指向目标字符串的指针。

示例:

#include <stdio.h>  
#include <string.h>  
  
int main() {  
    char source[] = "Hello, World!";  
    char destination[50];  
      
    strcpy(destination, source);  
      
    printf("The destination string is: %s\n", destination);  
    return 0;  
}

 输出:

The destination string is: Hello, World!

注意事项:

  1. 使用 strcpy 时必须确保目标字符串有足够的空间来存储源字符串的内容,包括末尾的空字符。如果目标字符串的空间不足以容纳源字符串,就会发生缓冲区溢出,这可能导致程序崩溃或更严重的安全问题。
  2. strcpy 不会检查目标数组的大小,因此在使用它之前,程序员必须确保目标数组足够大。为了避免缓冲区溢出,可以考虑使用 strncpy 函数,它允许你指定一个最大字符数来限制复制的字符数量。
  3. strcpy 不会检查源字符串是否为 NULL,所以在使用之前应该确保源字符串是有效的。
strcat:

作用:

strcat 函数的作用是将一个字符串(源字符串)连接到另一个字符串(目标字符串)的末尾。它会找到目标字符串中的终止空字符('\0'),然后在这个位置后追加源字符串的所有字符(包括其自身的终止空字符)。

解释:

在 C 语言中,字符串是通过字符数组来表示的,并且以空字符('\0')作为结束标志。strcat 函数接受两个参数:第一个参数是目标字符串,第二个参数是要追加的源字符串。函数会将源字符串的内容复制到目标字符串的末尾,并确保新的字符串也以空字符结束。

函数原型:

char *strcat(char *dest, const char *src);

1. dest 是指向目标字符串的指针。

2.  src 是指向源字符串的指针,即要追加到目标字符串末尾的字符串。这里的 const 修饰符表示在函数执行过程中,src 所指向的字符串内容不会被修改。

返回值:

strcat 函数返回指向目标字符串 dest 的指针

示例:

#include <stdio.h>  
#include <string.h>  
  
int main() {  
    char str1[50] = "Hello";  
    char str2[] = ", World!";  
      
    strcat(str1, str2);  
      
    printf("%s\n", str1);  
    return 0;  
}

输出:

Hello, World!

注意事项:

  1. 使用 strcat 函数之前,必须确保目标字符串 dest 已经分配了足够的空间来容纳源字符串 src 的内容,包括终止的空字符。否则,如果目标字符串的空间不足以容纳追加的内容,就会发生缓冲区溢出,这可能导致程序崩溃或引发更严重的安全问题。
  2. 为了避免缓冲区溢出,你可以使用 strncat 函数,它允许你指定一个最大字符数来限制追加的字符数量。
 strcmp:

作用:

strcmp 函数的主要作用是按照字典顺序比较两个字符串。它会逐个比较两个字符串中的对应字符,直到出现不同的字符或者遇到字符串结束符('\0')为止。

解释:

在 C 语言中,字符串是通过字符数组来表示的,并且以空字符('\0')作为结束标志。strcmp 函数会按照 ASCII 码的顺序,从两个字符串的第一个字符开始比较,如果两个字符相等,则继续比较下一个字符;如果两个字符不相等,则根据它们的 ASCII 码大小返回相应的结果。

比较规则:

  • 如果 str1 和 str2 完全相同(包括长度和内容),则 strcmp 返回 0。
  • 如果 str1 在字典顺序上小于 str2,则 strcmp 返回一个负数。
  • 如果 str1 在字典顺序上大于 str2,则 strcmp 返回一个正数。

函数原型:

int strcmp(const char *str1, const char *str2);

1 .str1 和 str2 是指向要比较的两个字符串的指针。 

2 . 函数返回一个整数,表示两个字符串的比较结果。

示例:

#include <stdio.h>  
#include <string.h>  
  
int main() {  
    char str1[] = "apple";  
    char str2[] = "banana";  
    char str3[] = "apple";  
      
    int result1 = strcmp(str1, str2); // 比较 "apple" 和 "banana"  
    int result2 = strcmp(str1, str3); // 比较 "apple" 和 "apple"  
      
    if (result1 < 0) {  
        printf("str1 is less than str2\n");  
    } else if (result1 > 0) {  
        printf("str1 is greater than str2\n");  
    } else {  
        printf("str1 is equal to str2\n");  
    }  
      
    if (result2 == 0) {  
        printf("str1 is equal to str3\n");  
    } else {  
        printf("str1 is not equal to str3\n");  
    }  
      
    return 0;  
}

输出:

str1 is less than str2
str1 is equal to str3

注意事项:

  1. 使用 strcmp 时,应确保两个字符串指针都是有效的,且指向的字符串以空字符结束。
  2. strcmp 是区分大小写的,即它会根据字符的 ASCII 码值进行比较,因此大写和小写字母被视为不同的字符。如果需要不区分大小写的比较,可以使用其他方法或自定义比较函数。
字符串案例:
  • 需求:自定义一个函数my_strlen(),实现的功能和strlen一样
  • 示例代码:
#include <stdio.h>

// 函数定义
int my_strlen(char * temp) {
    // 定义一个累加个数的变量,初始值为0
    int i = 0;
    // 循环遍历每一个字符,如果是'\0'跳出循环
    while (temp[i] != '\0') {
        // 下标累加
        i++;
    }

    return i;
}

int main() {
    char *p = "hello";
    // 函数调用
    int n = my_strlen(p);
    printf("n = %d\n", n);

    return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【笔记】ASP.NET Core 2.2 Web API —— 学习笔记

当年刚接触 ASP.NET Core 2.2 时&#xff0c;留下的学习笔记。现在把它挪到 CSDN&#xff0c;也是对过去学习 ASP.NET Core 痕迹进行记录。 VS 2019 ASP.NET Core 2.2 sqlSugarCore (ORM) 1. 仓储模式 服务 抽象接口 1.1 新建asp.net core 2.2 WebApi项目 nmmking.Core.…

安全中级-环境安装(手动nginx以及自动安装php,mysql)

为了方便大家跟bilibili课程&#xff0c;出了第一节环境 bilibili搜凌晨五点的星可以观看相关的教程 一、环境 ubentu 二、nginx手动安装 2.1第一步 wget https://nginx.org/download/nginx-1.24.0.tar.gz 2.2下载好安装包以后解压 tar -zxvf nginx-1.21.6.tar.gz2.3安…

CTFHUB-技能树-Web前置技能-文件上传(前端验证—MIME绕过、00截断、00截断-双写后缀)

CTFHUB-技能树-Web前置技能-文件上传&#xff08;前端验证—MIME绕过、00截断、00截断-双写后缀&#xff09; 文章目录 CTFHUB-技能树-Web前置技能-文件上传&#xff08;前端验证—MIME绕过、00截断、00截断-双写后缀&#xff09;前端验证—MIME绕过有关MIMEMIME的作用 解题时有…

【学习笔记】Vue3源码解析:第四部分- runtime-dom(1)

课程地址&#xff1a;【已完结】全网最详细Vue3源码解析&#xff01;&#xff08;一行行带你手写Vue3源码&#xff09; 第四部分-&#xff1a;&#xff08;对应课程的第24-26节&#xff09; 第24节&#xff1a;《理解runtime-dom的作用》 源码中除了 dep.ts &#xff0c;其余基…

设计模式——备忘录模式18

备忘录模式将创建状态快照 /备份的工作委派给实际状态的拥有者 &#xff08;Originator&#xff09; 对象。 这样其他对象就不再需要从 “外部” 复制文件状态了&#xff0c; 拥有者拥有其文件状态的完全访问权&#xff0c; 因此可以自行生成快照。 设计模式&#xff0c;一定要…

Linux-时间同步服务器

1. (问答题) 一.配置server主机要求如下&#xff1a; 1.server主机的主机名称为 ntp_server.example.com 编写脚本文件 #!/bin/bash hostnamectl hostname ntp_server.example.com cd /etc/NetworkManager/system-connections/ rm -fr * cat > eth0.nmconnection <&…

SpringBoot相关知识点总结

1 SpringBoot的目的 简化开发&#xff0c;开箱即用。 2 Spring Boot Starter Spring Boot Starter 是 Spring Boot 中的一个重要概念&#xff0c;它是一种提供依赖项的方式&#xff0c;可以帮助开发人员快速集成各种第三方库和框架。Spring Boot Starter 的目的是简化 Sprin…

【架构-14】数据库性能优化方式

数据库出现性能瓶颈对外的表现为&#xff1a; 大量请求阻塞SQL操作变慢存储出现问题 为解决上述出现的问题&#xff0c;因此推出了一系列的数据库性能优化方式。 数据库性能优化是提高数据库系统性能和响应时间的关键任务。以下是一些常见的 数据库性能优化方式&#xff1a; …

力扣152. 乘积最大子数组

Problem: 152. 乘积最大子数组 文章目录 题目描述思路复杂度Code 题目描述 思路 1.初始化&#xff1a;首先&#xff0c;我们创建两个数组maxNum和minNum&#xff0c;并将它们初始化为输入数组nums。这两个数组用于存储到当前位置的最大和最小乘积。我们还需要一个变量maxProduc…

51单片机之DS1302实时时钟

1.DS1302时钟芯片介绍 DS1302是由美国DALLAS公司推出的具有涓细电流充电能力的低功耗实时时钟芯片。它可以对年、月、日、周、时、分、秒进行计时&#xff0c;且具有闰年补偿等多种功能RTC(Real Time Clock)&#xff1a;实时时钟&#xff0c;是一种集成电路&#xff0c;通常称…

HTML段落标签、换行标签、文本格式化标签与水平线标签

目录 HTML段落标签 HTML换行标签 HTML格式化标签 加粗标签 倾斜标签 删除线标签 下划线标签 HTML水平线标签 HTML段落标签 在网页中&#xff0c;要把文字有条理地显示出来&#xff0c;就需要将这些文字分段显示。在 HTML 标签中&#xff0c;<p>标签用于定义段落…

【前端】1. HTML【万字长文】

HTML 基础 HTML 结构 认识 HTML 标签 HTML 代码是由 “标签” 构成的. 形如: <body>hello</body>标签名 (body) 放到 < > 中大部分标签成对出现. <body> 为开始标签, </body> 为结束标签.少数标签只有开始标签, 称为 “单标签”.开始标签和…

一次配置Docker环境的完整记录

一次配置Docker环境的完整记录 Docker环境搭建报错与解决报错一报错二报错三 Docker环境搭建 本节介绍了一次配置docker环境的完整记录&#xff1a; 编写Dockerfile文件&#xff1a; FROM pytorch/pytorch:1.10.0-cuda11.3-cudnn8-develRUN rm /etc/apt/sources.list.d/cuda.l…

C++设计模式|创建型 2.工厂模式

1.简单工厂思想 简单工厂模式不属于23种设计模式之⼀&#xff0c;更多的是⼀种编程习惯。它的核心思想是将产品的创建过程封装在⼀个⼯⼚类中&#xff0c;把创建对象的流程集中在这个⼯⼚类⾥⾯。卡码网将其结构描述为下图所示的情况&#xff1a; 简单⼯⼚模式包括三个主要⻆⾊…

zabbix 自动发现与自动注册 部署 zabbix 代理服务器

zabbix 自动发现&#xff08;对于 agent2 是被动模式&#xff09; zabbix server 主动的去发现所有的客户端&#xff0c;然后将客户端的信息登记在服务端上。 缺点是如果定义的网段中的主机数量多&#xff0c;zabbix server 登记耗时较久&#xff0c;且压力会较大。1.确保客户端…

uboot的移植

文章目录 一、官方uboot移植1.Uboot系统复制到Ubuntu系统2.解压Uboot系统3.编译Uboot系统4.生成可执行文件5.将u-boot.bin烧录到SD卡6.SD卡插入到板子&#xff0c;启动方式选择SD卡7.复位板子&#xff0c;查看打印信息&#xff0c;编译时间是否正常 二、根据官方提供的uboot添加…

frp 内网穿透配置(v0.55.1 版本)

注意&#xff1a;从 [v0.52.0] 版本开始&#xff0c;配置文件由 frps.ini 改成了 frps.toml 一种快速反向代理&#xff0c;可帮助您将 NAT 或防火墙后面的本地服务器暴露给 Internet。 GitHub 地址 &#xff1a; github.com/fatedier/fr… 下载之后如果碰到杀毒软件报毒&#x…

富文本在线编辑器 - tinymce

tinymce 项目是一个比较好的富文本编辑器. 这里有个小demo, 下载下来尝试一下, 需要配置个本地服务器才能够访问, 我这里使用的nginx, 下面是我的整个操作过程: git clone gitgitee.com:chick1993/layui-tinymce.git cd layui-tinymcewget http://nginx.org/download/nginx-1.…

00_Qt概述以及如何创建一个QT新项目

Qt概述 1.Qt概述1.1 什么是Qt1.2 Qt的发展史1.3 支持的平台1.4 Qt版本1.5 Qt的下载与安装1.6 Qt的优点 2.QT新项目创建3.pro文件4.主函数5.代码命名规范和快捷键 1.Qt概述 1.1 什么是Qt Qt是一个跨平台的C图形用户界面应用程序框架。它为应用程序开发者提供建立艺术级图形界面…

【一竞技CS2】VP战队官宣签下electroNic取代mir

1、近日VP战队官宣签下electroNic&#xff0c;以取代阵容中的mir。 electroNic自己也表示&#xff1a;“VP是一支顶级队伍。阵容核心曾赢得Major冠军&#xff0c;所有队员都处于巅峰状态并且时刻准备着去争夺冠军。我们有着一样的雄心壮志。 此外我还对和Jame很感兴趣&#xf…