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 语言内存模型的关键一步。

相关推荐
光军oi4 小时前
JAVA全栈JVM篇————初识JVM
java·开发语言·jvm
Moniane4 小时前
C++深度解析:从核心特性到现代编程实践
java·开发语言·jvm
uxiang_blog4 小时前
C++进阶:重载类型转换
linux·开发语言·c++
爱编程的鱼5 小时前
C# 参数详解:从基础传参到高级应用
开发语言·microsoft·c#
Michael_lcf5 小时前
Java的UDP通信:DatagramSocket和DatagramPacket
java·开发语言·udp
道之极万物灭5 小时前
Python操作word实战
开发语言·python·word
moringlightyn5 小时前
c++11可变模版参数 emplace接口 新的类功能 lambda 包装器
开发语言·c++·笔记·其他·c++11·lambda·包装器
Laplaces Demon5 小时前
Spring 源码学习(十四)—— HandlerMethodArgumentResolver
java·开发语言·学习
郝学胜-神的一滴5 小时前
使用Linux系统函数递归遍历指定目录
linux·运维·服务器·开发语言·c++·软件工程