首页 > 其他分享 >c语言基础--------字符串指针

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

时间:2024-08-20 19:58:25浏览次数:13  
标签:-------- 字符 指向 char 数组 字符串 指针

在 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 关键字可以确保函数不会修改传入的字符串,这是一个好的编程实践。

在这里插入图片描述

标签:--------,字符,指向,char,数组,字符串,指针
From: https://blog.csdn.net/yuanbenshidiaos/article/details/141366911

相关文章

  • 2024浙江省信息通信行业职业技能竞赛信息安全测试员竞赛CTF比赛
    浙江省信息通信行业职业技能竞赛信息安全测试员竞赛CTF比赛MISC部分Author:Ns100kUpFrom:极安云科-服务中心Data:2024/08/07Copyright:本内容版权归属极安云科,未经授权不得以任何形式复制、转载、摘编和使用。培训、环境、资料、考证公众号:Geek极安云科网络安全群:62403......
  • Postman中Body添加注释后请求报错问题解决【保姆级教程!!!】
    本文介绍关于Postman中Body添加注释后请求报错问题解决方法如:请求返回下述报错操作失败!系统异常,JsonParseException:Unexpectedcharacter(‘/’(code47)):maybea(non-standard)comment?(notrecognizedasonesinceFeature‘ALLOW_COMMENTS’notenabled......
  • 汇编世界的桥梁:链接器与加载器的奥秘
    标题:汇编世界的桥梁:链接器与加载器的奥秘在计算机程序的生命周期中,链接器(Linker)和加载器(Loader)扮演着至关重要的角色。它们是汇编语言程序从源代码到可执行程序过程中的关键环节。本文将深入探讨链接器和加载器的作用、工作原理以及它们在程序运行中的重要性。一、链接器(L......
  • 【Azure Fabric Service】Service Fabric部署失败问题 Provisioning of VM extension
    问题描述ServiceFabric部署失败,错误信息:ProvisioningofVMextensionConfigureVMhastimedout.  Extensionprovisioninghastakentoolongtocomplete.Theextensiondidnot reportamessage.Moreinformationontroubleshootingisavailableat https://aka......
  • CVE-2021-21315漏洞复现
    一、基本信息攻击机:kaliIP:192.168.100.60靶机:CentOS7IP:192.168.100.40二、攻击过程下载node.js环境wgethttps://nodejs.org/dist/v12.18.4/node-v12.18.4-linux-x64.tar.xztar-xvfnode-v12.18.4-linux-x64.tar.xzmvnode-v12.18.4-linux-x64nodejsmvnodejs......
  • Netty 异步任务模型 及 Future-Listener 机制
    https://cloud.tencent.com/developer/article/2246990一、Netty模型二、异步模型三、Future-Listener机制四、Future-Listener机制代码示例 以服务器端为例1.线程池:Netty模型核心就是两个线程池,BossGroup线程池和WorkerGroup线程池;①BossGroup......
  • Swift操作符重载:编程语言的瑞士军刀
    标题:Swift操作符重载:编程语言的瑞士军刀在Swift编程语言中,操作符重载是一种强大的特性,它允许开发者为自定义类型提供已有操作符的新实现。这不仅提升了代码的可读性,还增加了Swift语言的表达力。本文将深入探讨Swift中操作符重load的机制,并展示如何通过代码示例来实现它。......
  • 针对ShotGun的ServerRewind
    区别虽然也是HitScane,但其可以对多个角色或者多个部位造成伤害更改首先是之前在FFramePackage结构体中,需要增添一个成员变量,用来表示该结构体中的BoxCollision属于哪个敌人。而之前使用的ConfirmHit返回的校验击中头部和身体的结构体,需要为ShotGun创建类似的,其内有两个TMap类......
  • 网络丢包深度解析:影响、原因及优化策略
    摘要网络丢包是数据在传输过程中未能成功到达目的地的现象,它对网络通信的性能有着显著的影响。本文将深入探讨网络丢包的定义、原因、对性能的影响,以及如何通过技术手段进行检测和优化。1.网络丢包的定义网络丢包发生在数据包在源和目的地之间的传输过程中,由于各种原因......
  • 网络模型图,网络通信三要素
    网络模型7层概述:1.物理层:主要定义物理设备标准,如网线的接口类型、光纤的接口类型、各种传输介质的传输速率等。它的主要作用是传输比特流(就是由1、0转化为电流强弱来进行传输,到达目的地后在转化为1、0,也就是我们常说的数模转换与模数转换)。这一层的数据叫做比特。2.数据链路......