嵌入式学习之路 15(C语言基础学习——指针操作一维字符型数组)

  1. 字符型数组的定义和初始化

    • char s[] = "hello";:在栈上开辟空间并初始化。
    • const char *p = "hello";:指针 p 指向字符串常量区的 "hello",只能读取不能修改。
  2. 指针变量的类型确定

    • 指针变量的类型由其所指向的数据的类型决定。
    • 例如,char * 指向字符型数据,int * 指向整型数据。
  3. 处理字符串的方式

    • 直接定义字符数组存储字符串。
    • 使用指针指向字符串常量。
  4. const 关键字

在指针操作一维字符型数组时,将形参设计为 const char * 具有重要的意义和好处。其目的在于防止函数内部对传入的字符指针所指向的内容进行误操作,增强程序的安全性和稳定性。

好处主要体现在以下几个方面:

  1. 能够将可能在运行时出现的问题提前到编译时发现。例如,如果在函数内部试图修改被声明为 const 的字符指针所指向的内容,编译器会报错,从而提前避免潜在的错误。
  2. const char * 这种类型的形参具有很强的通用性,可以接收 char * 类型和 const char * 类型的实参。实参可以是数组名、指针变量(char *pconst char *p),也可以是直接的字符串常量。这极大地提高了参数的适用性。

不同的指针声明方式:

  1. const char *schar const *s 表示所指向的字符内容是只读的,不能通过 *s 来修改其指向的字符内容。
  2. char * const s 表示指针 s 本身是只读的,不能指向其他的地址。

const 限定基类型的情况:

  1. const int *p = &aint const *p = &a 表示不能通过 *p 的方式修改 a 的值。
  2. int * const p = &a 表示指针 p 不能被修改,即不能指向其他变量。

在实际应用中:

  1. 如果不想通过 *p 的方式改变基类型对应的数据,可以使用 const int *p = &aint const *p = &a
  2. 如果指针变量 p 定义好后不想再指向别的变量,则使用 int * const p = &a

对于指针和字符串的关系,在 C 语言中字符串通常以字符数组的形式存储。例如 char s[] = "hello"; 是在栈上开辟一块空间,并使用字符串常量 "hello" 进行初始化。而 const char *p = "hello"; 表示 p 指向了字符串常量区中的 "hello" ,由于是指向字符串常量区,所以只能进行读取操作,不能对其进行修改。

例如,如果尝试这样修改:

cpp 复制代码
const char *p = "hello";
*p = 'H';  // 这会导致编译错误,因为不能修改字符串常量区的内容

而对于 char s[] = "hello"; 则可以进行修改:

cpp 复制代码
char s[] = "hello";
s[0] = 'H';  // 这是合法的修改

练习:用指针操作的方式实现系统函数的功能

gets

puts

strlen

strcpy /strncpy

strcat /strncat

strcmp /strncmp

cpp 复制代码
#include <stdio.h>
#include <string.h>

// 从标准输入获取字符串并存储到指定字符数组
char * Gets(char *s)
{
    char *ret = s;

    while ( (*s = getchar())!= '\n' )
    {
        s++;
    }
    *s = '\0';

    return ret;
}

// 输出字符串
int Pust(const char *s)
{
    while ( *s!= '\0' )
    {
        putchar(*s);
        s++;
    }
    printf("\n");

    return 0;
}

// 计算字符串长度
size_t Strlen(const char *s)
{
    const char *ret = s;
    while ( *s!= '\0')
    {
        s++;
    }

    return s - ret;
}

// 连接两个字符串
char *Strcat(char *dest, const char *src)
{
    char *ret = dest;

    while ( *dest!= '\0' )
        dest++;

    while ( *src!= '\0' )
    {
        *dest = *src;
        dest++;
        src++;
    }
    *dest = '\0';

    return ret;
}

// 连接指定长度的两个字符串
char *Strncat(char *dest, const char *src, size_t n)
{
    char *ret = dest;

    while ( *dest!= '\0' )
        dest++;

    while ( *src!= '\0' && n )
    {
        *dest = *src;
        dest++;
        src++;
        n--;
    }
    *dest = '\0';

    return ret;
}

// 复制字符串
char * Strcpy(char *dest, char *src)
{
    char *ret = dest;

    while( *src!= '\0' )
    {
        *dest = *src;
        dest++;
        src++;
    }
    *dest = '\0';

    return ret;
}

// 复制指定长度的字符串
char * Strncpy(char *dest, char *src, size_t n)
{
    char *ret = dest;

    while( *src!= '\0' && n!= 0 )
    {
        *dest = *src;
        dest++;
        src++;
        n--;
    }

    while ( n )
    {
        *dest = '\0';
        *dest++;
        n--;
    }

    return ret;
}

// 比较两个字符串
int Strcmp(const char *dest, const char *src)
{
    while ( *dest == *src && *dest!= '\0' && *src!= '\0' )
    {
        dest++;
        src++;
    }

    return *dest - *src;
}

// 比较指定长度的两个字符串
int Strncmp(const char *dest, const char *src, size_t n)
{
    while ( *dest == *src && *dest!= '\0' && *src!= '\0' && n > 1 )
    {
        dest++;
        src++;
        n--;
    }

    return *dest - *src;
}

// 主函数,用于测试上述函数
int main()
{
    // 定义并初始化字符数组 a
    char a[20];
    // 调用 Gets 函数获取用户输入并存储到 a 中
    Gets(a);

    char s[100];
    // 调用 Gets 函数获取用户输入并存储到 s 中
    Gets(s);

    // 调用 Strncmp 函数比较 a 和 s 的前 3 个字符,并输出结果
    printf("%d\n", Strncmp(a, s, 3));

    return 0;
}
相关推荐
2301_795167201 小时前
玩转Rust高级应用 如何避免对空指针做“解引用”操作,在C/C++ 里面就是未定义行为
c语言·c++·rust
智驱力人工智能3 小时前
基于视觉分析的人脸联动使用手机检测系统 智能安全管理新突破 人脸与手机行为联动检测 多模态融合人脸与手机行为分析模型
算法·安全·目标检测·计算机视觉·智能手机·视觉检测·边缘计算
2301_764441333 小时前
水星热演化核幔耦合数值模拟
python·算法·数学建模
循环过三天3 小时前
3.4、Python-集合
开发语言·笔记·python·学习·算法
昌sit!5 小时前
Linux系统性基础学习笔记
linux·笔记·学习
学会沉淀。5 小时前
设备如何“开口说话”?
学习
priority_key5 小时前
排序算法:堆排序、快速排序、归并排序
java·后端·算法·排序算法·归并排序·堆排序·快速排序
不染尘.6 小时前
2025_11_7_刷题
开发语言·c++·vscode·算法
m0_591338916 小时前
day10数组的学习
学习
ben9518chen6 小时前
嵌入式Linux C语言程序设计九
linux·c语言