c语言基础--------字符串指针

34 篇文章 0 订阅
26 篇文章 0 订阅

在 C 语言中,字符串指针是一个指向字符类型的指针,通常用于指向字符串的第一个字符。字符串在 C 语言中通常表示为字符数组,而字符串指针则是用来存储这种字符数组首地址的变量。

定义字符串指针

字符串指针的定义方式如下:

char *stringPtr;

这里的 char * 表示 stringPtr 是一个指向 char 类型的指针,它可以用来指向一个字符串。

初始化字符串指针

字符串指针可以通过以下方式初始化:

char *stringPtr = "Hello, World!";

在这个例子中,stringPtr 被初始化为指向一个字符串常量 “Hello, World!” 的第一个字符。

使用字符串指针

字符串指针可以用来访问和操作字符串。以下是一些使用字符串指针的示例:

#include <stdio.h>
int main() {
    char *stringPtr = "Hello, World!";
    // 使用字符串指针打印字符串
    printf("%s\n", stringPtr);
    // 访问字符串中的单个字符
    for (int i = 0; stringPtr[i] != '\0'; i++) {
        printf("%c ", stringPtr[i]);
    }
    printf("\n");
    return 0;
}

在上面的代码中,stringPtr 指向了一个字符串常量。使用 %s 格式化字符串可以打印整个字符串。通过循环和数组下标的方式,可以逐个访问字符串中的字符,直到遇到空字符 \0,这表示字符串的结束。

字符串指针与字符数组的区别

字符串指针与字符数组在 C 语言中是不同的:

  • 字符串指针:是一个指针,它存储的是字符串的首地址。
  • 字符数组:是一个数组,它存储的是字符串本身。
    以下是一个字符数组的示例:
char strArray[] = "Hello, World!";

在这个例子中,strArray 是一个字符数组,它包含了 “Hello, World!” 字符串的所有字符,包括结尾的空字符 \0

注意事项

  • 字符串指针可以指向字符串常量,但是不能直接修改字符串常量中的内容,因为这通常会导致未定义的行为。
  • 当使用字符串指针时,应当注意避免越界访问,即不要访问字符串结束标记 \0 之后的内存。
    字符串指针是 C 语言中处理字符串的一种基本方式,理解和掌握它们的使用对于 C 语言编程非常重要。

字符数组 与字符指针的区别

在 C 语言中,字符数组和字符指针虽然都可以用来处理字符串,但它们在概念、用途和内存布局上存在一些关键的区别。

定义和内存布局

  1. 字符数组
    • 定义:字符数组是一个数组,其元素类型为 char,用于存储一系列字符。
    • 内存布局:字符数组在内存中分配一块连续的空间来存储字符序列,包括字符串的结束标志 \0
      示例:
    char strArray[20] = "Hello, World!";
    
  2. 字符指针
    • 定义:字符指针是一个指向 char 类型的指针,通常用于指向字符串的第一个字符。
    • 内存布局:字符指针本身只占用一个指针大小的内存(通常是 4 或 8 字节,取决于系统架构),它存储的是字符串首地址。
      示例:
    char *strPtr = "Hello, World!";
    

在这里插入图片描述

内容修改

  1. 字符数组
    • 可以直接修改数组中的字符,因为数组分配了内存空间来存储这些字符。
      示例:
    strArray[0] = 'h'; // 将第一个字符修改为小写的 'h'
    
  2. 字符指针
    • 通常指向字符串常量,这些常量存储在程序的只读数据段中,因此直接尝试修改这些字符可能会导致运行时错误或未定义行为。
    • 如果字符指针指向的是可修改的内存(如动态分配的内存或字符数组),则可以修改它所指向的内容。
      示例(错误用法):
    strPtr[0] = 'h'; // 错误:如果 strPtr 指向字符串常量,这将导致未定义行为
    

大小和生命周期

  1. 字符数组
    • 的大小在编译时确定,且在函数作用域结束时自动释放。
    • 的大小必须足够大,以容纳字符串及其结束标志 \0
  2. 字符指针
    • 自身的大小是固定的,不随指向的字符串长度变化。
    • 指向的字符串的生命周期不受字符指针的生命周期影响。
      在这里插入图片描述

作为函数参数

  1. 字符数组
    • 作为参数传递时,实际上传递的是数组的首地址,但数组的大小不会被传递。
  2. 字符指针
    • 作为参数传递时,传递的也是字符串的首地址,但不需要知道字符串的长度。

总结

以下是字符数组和字符指针的主要区别的总结:

  • 内存分配:字符数组在栈上分配内存,而字符指针本身在栈上分配内存,它指向的字符串可能在栈上、堆上或只读数据段中。
  • 修改能力:字符数组的内容可以被修改,而字符指针指向的字符串常量通常不能被修改。
  • 大小:字符数组的大小取决于其存储的字符数量,而字符指针的大小是固定的。
    理解这些区别对于正确使用字符数组和字符指针至关重要。
    下面是字符数组和字符指针的代码示例,以及它们之间的区别:
#include <stdio.h>
#include <string.h>
int main() {
    // 字符数组示例
    char strArray[20] = "Hello, World!"; // 分配了20个字符的空间
    // 修改字符数组中的内容
    strArray[0] = 'h'; // 将第一个字符修改为小写的 'h'
    // 打印字符数组
    printf("Character array: %s\n", strArray);
    // 字符指针示例
    char *strPtr = "Hello, World!"; // 指向一个字符串常量
    // 尝试修改字符指针指向的内容(这是错误的,会导致未定义行为)
    // strPtr[0] = 'h'; // 错误,不要这样做!
    // 打印字符指针指向的字符串
    printf("Character pointer: %s\n", strPtr);
    // 字符指针指向动态分配的内存示例
    char *dynamicStr = malloc(20 * sizeof(char)); // 动态分配内存
    if (dynamicStr != NULL) {
        strcpy(dynamicStr, "Hello, Dynamic World!"); // 复制字符串到动态分配的内存
        // 修改动态分配内存中的内容
        dynamicStr[0] = 'h'; // 这是合法的,因为我们分配了可写的内存
        // 打印修改后的动态字符串
        printf("Dynamic string: %s\n", dynamicStr);
        // 释放动态分配的内存
        free(dynamicStr);
    }
    return 0;
}

在这个示例中:

  • strArray 是一个字符数组,它被初始化为 “Hello, World!”,并且我们修改了它的第一个字符为小写的 ‘h’。
  • strPtr 是一个字符指针,它指向一个字符串常量 “Hello, World!”。尝试直接修改 strPtr 指向的字符串是错误的,因为这会试图修改只读内存。
  • dynamicStr 是一个指向动态分配内存的字符指针。我们可以安全地修改 dynamicStr 指向的内容,因为它指向的是我们分配的可写内存。在使用完毕后,我们使用 free 函数释放了这块内存。
    这个示例展示了字符数组和字符指针在定义、内存分配、修改能力以及作为函数参数时的不同用法。

在这里插入图片描述

字符指针作为函数参数

在 C 语言中,字符指针经常被用作函数参数,尤其是在处理字符串时。以下是如何使用字符指针作为函数参数的几个示例。

示例 1:打印字符串

一个简单的函数,它接收一个字符指针作为参数并打印字符串。

#include <stdio.h>
void printString(const char *str) {
    printf("%s\n", str);
}
int main() {
    char *str = "Hello, World!";
    printString(str); // 调用函数并传递字符串
    return 0;
}

在这个例子中,printString 函数接收一个指向 char 的指针 str,它指向一个字符串。函数使用 printf 来打印这个字符串。

示例 2:计算字符串长度

一个函数,它接收一个字符指针作为参数并返回字符串的长度。

#include <stdio.h>
#include <string.h>
int stringLength(const char *str) {
    int length = 0;
    while (*str != '\0') {
        length++;
        str++;
    }
    return length;
}
int main() {
    char *str = "Hello, World!";
    int len = stringLength(str); // 调用函数并传递字符串
    printf("The length of the string is: %d\n", len);
    return 0;
}

在这个例子中,stringLength 函数通过遍历字符串直到遇到空字符 \0 来计算字符串的长度。

示例 3:字符串复制

一个函数,它接收两个字符指针作为参数,并将源字符串复制到目标缓冲区。

#include <stdio.h>
#include <string.h>
void copyString(char *dest, const char *src) {
    while ((*dest = *src) != '\0') {
        dest++;
        src++;
    }
}
int main() {
    char src[] = "Hello, World!";
    char dest[20]; // 确保有足够的空间来存储复制的内容
    copyString(dest, src); // 调用函数并传递源字符串和目标缓冲区
    printf("Copied string: %s\n", dest);
    return 0;
}

在这个例子中,copyString 函数将源字符串 src 复制到目标缓冲区 dest 中。注意,目标缓冲区需要有足够的空间来存储源字符串及其结束标志 \0

注意事项

  • 当使用字符指针作为函数参数时,应当注意不要修改指针所指向的字符串常量。
  • 如果函数内部需要修改字符串,应该传递指向可修改内存的指针,例如动态分配的内存或字符数组。
  • 使用 const 关键字可以确保函数不会修改传入的字符串,这是一个好的编程实践。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jing静~

ლ(°◕‵ƹ′◕ლ)让我一键努

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值