C++字符指针常用写法

C++字符指针常用写法

case 1 不指定数组大小,直接用字符赋值
char ch[] = {"abcdefg"};
cout<<ch<<endl; // 输出  abcdefg
cout<<strlen(ch)<<endl; // 输出 7, strlen 输出的是字符长度 
cout<<sizeof(ch)<<endl; // 输出 8,sizeof 输出的是变量实际所占空间的长度,字符数组最后一个元素 \0 占一个空间
case 2 遍历字符数组 or char*

方式1

    for (int i = 0; i < strlen(ch); i++) {
        cout<<ch[i]<<" ";
    }
    cout<<endl;

方式2

    for (int i = 0; i < strlen(ch); i++) {
        cout<<*(ch + i)<<" ";
    }
    cout<<endl;

方式3

    while (*(ch + i) != '\0') {
        cout<<*(ch + i)<<endl;
        i++;
    }
case 3 动态申请 char 数组
char *ch = new char[11];
cout<<strlen(ch)<<endl; // 输出 0
cout<<sizeof(ch)<<endl; // 输出 8 ,此时ch是指针地址,不管ch里面是否填充了字符,它的大小适中为 8 
char *ch = new char[11];
ch[0] = 'a';
ch[1] = 'b';
cout<<strlen(ch)<<endl; // 输出 2
cout<<sizeof(ch)<<endl; // 输出 8
case 4 先申请固定大小的空间,再遍历赋值

法1 申请空间,用new。

法2 不使用new去动态申请,直接固定好大小

需要注意的是,最后要给 ‘\0’ 保留一个位子,不然输出的结果就会错误

    char ch[10];
    cout<<strlen(ch)<<endl;
    cout<<sizeof(ch)<<endl;
    for (int i = 0; i < sizeof(ch) - 1; i++) { // size 注意减1
        ch[i] = i + '0';
    }
    //ch[10 - 1] = '\0'; // 可以不写,系统会自动添加
    cout<<ch<<endl; // 输出 012345678
    return 0;
<think>好的,我现在需要帮助用户理解如何在C++中使用字符指针获取字符串的首地址。用户已经提到了内联汇编的方法,但可能他们现在想了解更基础的C++方法,而不涉及汇编。根据提供的引用内容,特别是引用[1]、[2]和[4],我需要综合这些信息来解释不同情况下如何获取首地址。 首先,用户的问题是关于字符指针和获取首地址的。我需要区分字符数组和字符指针的情况,因为它们的存储位置不同,获取首地址的方式可能也有所不同。根据引用[4],字符数组存储在全局数据区或栈区,而字符指针指向的字符串在常量区,这会影响它们的可修改性和地址获取方式。 然后,引用[1]和[2]都提到字符串变量名本身就是首地址,例如char str[]的情况下,str就是首地址。而用指针时,比如char* s = "Hello",s本身存储的就是首地址。但要注意的是,当使用字符数组时,数组名是首地址,而指针变量本身存储的地址值也是首地址。所以直接使用数组名或指针变量都可以得到首地址。 接下来,用户可能需要知道如何正确输出这个地址。引用[1]中的例子显示,直接输出指针变量会输出整个字符串,而使用static_cast<void*>可以正确输出地址。这是因为cout对char*有特殊处理,会将其视为C风格字符串,所以需要转换类型来显示地址。 另外,用户可能混淆了字符数组和字符指针的不同。例如,当使用char str[]时,数组名是首地址,而使用char* s时,s的值也是首地址,但两者的存储位置不同(栈区vs常量区),所以是否可以修改内容也不同。引用[4]详细说明了这一点,指出字符数组可读写,而指针指向的常量区字符串不可写。 用户还可能想知道如何在不同情况下获取首地址,比如对于string类对象。根据引用[3],string类的c_str()方法返回const char*,可以获取首地址,但需要注意其生命周期和const性质。 最后,需要总结注意事项,比如const修饰符的影响、不同存储区域的权限差异,以及如何安全地获取地址。可能还需要提醒用户避免未定义行为,如修改常量区字符串。</think>以下是C++中获取字符串首地址的详细解析,结合关键引用内容整理: --- ### 一、基础概念 1. **字符串存储本质** C++字符串以连续内存形式存储,末尾自动添加空字符`\0`。根据存储方式不同分为: - **字符数组**:存储在栈区或全局数据区(可读写) - **字符指针**:指向常量区的字符串(只读)[^4] 2. **首地址获取原理** 字符串名称本身即为首地址指针: ```cpp char arr[] = "Hello"; // arr即首地址 const char* ptr = "World"; // ptr存储的即首地址 ``` --- ### 二、具体获取方法 #### 1. 字符数组形式 ```cpp char str[] = "Hello World"; // 栈区数组 // 获取方式 cout << "首地址: " << (void*)str << endl; // 正确输出地址[^1] cout << "首字符地址: " << (void*)&str[0] << endl; // 等价写法 ``` #### 2. 字符指针形式 ```cpp const char* ptr = "Constant String"; // 常量区字符串 // 获取方式 cout << "首地址: " << (void*)ptr << endl; // 输出指针存储的地址[^2] cout << "首字符地址: " << (void*)&ptr[0] << endl; // 显式获取 ``` #### 3. string类对象 ```cpp #include <string> std::string s = "Modern C++"; // 获取方式 const char* p = s.c_str(); // 获取只读首地址[^3] cout << "首地址: " << (void*)p << endl; ``` --- ### 三、地址操作对比 | 操作 | 字符数组`char[]` | 字符指针`const char*` | `std::string` | |----------------------|------------------|------------------------|---------------| | 直接输出变量名 | 输出字符串内容 | 输出字符串内容 | 编译错误 | | `(void*)`转换 | 输出真实地址 | 输出真实地址 | 需`.c_str()` | | 允许修改内容 | ✔️ | ❌(常量区) | ✔️ | | 内存区域 | 栈/全局区 | 常量区 | 堆内存托管 | --- ### 四、关键注意事项 1. **const修饰符必要性** 字符指针必须声明为`const char*`以避免修改常量区数据导致的未定义行为[^4] 2. **输出地址的特殊处理** 必须使用强制类型转换`(void*)`,否则`cout`会按字符串内容输出而非地址[^1] 3. **地址有效性范围** - 字符数组:生命周期内地址始终有效 - `std::string::c_str()`:仅保证在字符串未修改前有效 --- ### 五、应用示例 ```cpp // 遍历字符串 const char* str = "Pointer"; for(int i=0; i<strlen(str); ++i) { cout << "字符地址: " << (void*)(str+i) << " 值: " << *(str+i) << endl; } /* 输出: 字符地址: 0x404000 值: P 字符地址: 0x404001 值: o ...(后续字符地址连续递增)*/ ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值