c语言14:字符指针

在 C 语言中,字符指针(char*) 是处理字符串的核心工具之一。

它不仅能灵活指向单个字符,还能高效操作字符串常量。今天,我们就从基础用法到深层原理,全面探究字符指针的奥秘。

一、字符指针的基础:指向单个字符

字符指针最朴素的用法,是指向单个字符变量,通过指针间接访问或修改字符的值。

看这段代码:

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

int main() 
{
    char ch = 'w';   // 定义字符变量ch,值为'w'
    char *pc = &ch;  // 字符指针pc指向ch的地址
    *pc = 'W';       // 通过解引用修改ch的值
    printf("ch = %c\n", ch);  // 输出:ch = W
    return 0;
}

关键逻辑:

  • char *pc 声明了一个字符指针变量 pc
  • &ch 获取字符变量 ch内存地址 ,并赋值给 pc,此时 pc 就 "指向" 了 ch
  • *pc解引用操作 ,表示 "访问 pc 指向地址的内容",因此 *pc = 'W' 等价于直接修改 ch 的值。

二、字符指针指向字符串常量:"地址" 而非 "内容"

字符指针更常见的场景,是指向字符串常量 。很多初学者会误解 "把整个字符串存到指针里",但本质是:指针存储的是字符串首字符的地址

看这个例子:

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

int main() 
{
    const char* pstr = "hello bit.";  // 字符指针pstr指向字符串首字符'h'的地址
    printf("%s\n", pstr);  // 输出:hello bit.
    return 0;
}

深层理解:

  • "hello bit."字符串常量 ,C/C++ 会将其存储在只读数据区(防止程序意外修改常量内容)。
  • const char* pstr 中的 const 表示 "指针指向的内容是常量"------ 即不能通过 pstr 修改字符串(比如 *pstr = 'H' 会触发编译错误)。
  • pstr 本身只存了首字符 'h' 的内存地址 ,而非整个字符串的内容。printf("%s", pstr) 能打印完整字符串,是因为 C 语言约定:字符串以 '\0'(空字符)结尾,printf 会从首地址开始,直到遇到 '\0' 才停止。

三、字符数组 vs 字符指针:内存模型的本质区别

为了彻底弄清字符指针与字符串的关系,我们对比字符数组指向常量字符串的字符指针------ 这也是面试高频考点。

看这段经典代码:

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

int main() 
{
    // 场景1:字符数组
    char str1[] = "hello bit.";
    char str2[] = "hello bit.";
    
    // 场景2:指向常量字符串的字符指针
    const char *str3 = "hello bit.";
    const char *str4 = "hello bit.";
    
    // 比较str1和str2
    if (str1 == str2)
        printf("str1 and str2 are same\n");
    else
        printf("str1 and str2 are not same\n");
    
    // 比较str3和str4
    if (str3 == str4)
        printf("str3 and str4 are same\n");
    else
        printf("str3 and str4 are not same\n");
    
    return 0;
}

运行结果:
str1 and str2 are not same
str3 and str4 are same

深度分析:

1. 字符数组 str1str2
  • char str1[] = "hello bit.";:程序会在栈内存 中为 str1 分配一块空间,然后把字符串 "hello bit."内容拷贝到这块空间里。
  • str2 同理:也是在栈上单独分配一块新内存,再拷贝字符串内容。
  • 因此,str1str2两块完全独立的内存 (地址不同),所以 str1 == str2 为假(== 比较的是地址,而非内容)。
2. 字符指针 str3str4
  • "hello bit."常量字符串 ,存储在只读数据区 。编译器为了优化内存,会让多个指针共享同一个常量字符串的内存(只要字符串内容相同)。
  • str3str4 都存储了这个常量字符串首字符 'h' 的地址 ,因此 str3str4 指向的是同一块内存 ,所以 str3 == str4 为真。

四、字符指针的实用场景

除了基础用法,字符指针在实际开发中还有诸多妙用:

1. 函数参数传递字符串(高效性)

通过字符指针传递字符串,无需拷贝整个字符串(只传地址),效率更高:

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

// 打印字符串的函数(接收字符指针)
void printString(const char *str) 
{
    printf("String: %s\n", str);
}

int main() 
{
    const char *msg = "Hello, Function!";
    printString(msg);  // 传递的是"地址",而非拷贝整个字符串
    return 0;
}

2. 动态分配字符串(灵活性)

结合 malloc 动态分配内存,可灵活控制字符串长度:

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

int main() 
{
    // 动态分配能存10个字符的空间(包含结束符'\0')
    char *dynamicStr = (char *)malloc(10 * sizeof(char));

    if (dynamicStr != NULL) // 检查内存是否分配成功
    {  
        strcpy(dynamicStr, "Dynamic");  // 拷贝字符串到动态内存
        printf("Dynamic String: %s\n", dynamicStr);
        free(dynamicStr);  // 用完后释放内存,避免泄漏
    }
    return 0;
}

五、总结

字符指针是 C 语言操作字符串的核心工具,核心要把握三点:

  • 字符指针既可以指向单个字符 ,也可以指向字符串常量的首地址
  • 字符串常量存储在只读数据区,相同的常量字符串可能被编译器优化为 "共享内存"。
  • 字符数组是 "存储字符串内容的内存块",而字符指针是 "指向字符串地址的工具"------ 二者在内存分配、比较逻辑上有本质区别。

掌握字符指针,不仅能更高效地操作字符串,也是理解 C 语言内存模型的关键一步。

相关推荐
马克学长2 分钟前
SSM基于Java的医疗器械销售系统oy281(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
java·开发语言·用户管理·ssm 框架·医疗器械销售系统
lqj_本人20 分钟前
Rust与Go:现代系统编程语言的深度对比
开发语言·golang·rust
星释37 分钟前
Rust 练习册 :Macros与宏系统
开发语言·后端·rust
l1t44 分钟前
利用短整数类型和部分字符串优化DuckDB利用数组求解数独SQL
开发语言·数据库·sql·duckdb
权泽谦1 小时前
从零搭建一个 PHP 登录注册系统(含完整源码)
android·开发语言·php
PieroPc1 小时前
用python Streamlit 做个RapidOCR 文本识别系统
开发语言·python·ocr
程序员东岸1 小时前
数据结构精讲:从栈的定义到链式实现,再到LeetCode实战
c语言·数据结构·leetcode
暖木生晖1 小时前
Javascript函数之匿名函数以及立即执行函数的使用方法?
开发语言·javascript·ecmascript
say_fall1 小时前
C语言容易被忽略的易错点(2)
c语言·开发语言
syker2 小时前
NEWBASIC 2.06.7 API 帮助与用户使用手册
开发语言·人工智能·机器学习·自动化