嵌入式学习之路 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;
}
相关推荐
垂杨有暮鸦⊙_⊙3 分钟前
阅读《先进引信技术的发展与展望》识别和控制部分_笔记
笔记·学习
大帅哥_6 分钟前
访问限定符
c语言·c++
kitesxian10 分钟前
Leetcode200. 岛屿数量(HOT100)
算法·深度优先
LNTON羚通15 分钟前
算法定制LiteAIServer视频智能分析平台工业排污检测算法智控环保监管
算法·目标检测·音视频·监控·视频监控
好好学习O(∩_∩)O19 分钟前
11-23刷题记录
算法·leetcode·职场和发展
小林熬夜学编程36 分钟前
【Linux系统编程】第五十弹---构建高效单例模式线程池、详解线程安全与可重入性、解析死锁与避免策略,以及STL与智能指针的线程安全性探究
linux·运维·服务器·c语言·c++·安全·单例模式
bingw011443 分钟前
华为机试HJ62 查找输入整数二进制中1的个数
数据结构·算法·华为
我qq不是4515165244 分钟前
C语言指针作业
c语言
苏言の狗1 小时前
小R的二叉树探险 | 模拟
c语言·数据结构·算法·宽度优先
加载中loading...1 小时前
C/C++实现tcp客户端和服务端的实现(从零开始写自己的高性能服务器)
linux·运维·服务器·c语言·网络