C++字符指针的特殊

  如果我们对一个非字符的指针进行操作,方法是这样的: 

  定义: 
    (1)int a=7; int *p=&a; 或者 
    (2)int a=7; int *p; p=&a; 或者 
    (3)int a=7; int *p; *p=a; 

  (1)这样定义的原因是因为等号两边的类型必须匹配,int *p=&a; 等号左边定义的是一个指针,指针的内容是地址,所以等号右边也应该是地址,&a就是取空间a的地址; 
    (2)int *p; p=&a; 为什么不是 *p=&a 而是 p=&a; 因为在定义的时候“*”只是说明p是一个指针,而p也是一个变量,不过是储存地址的一种特殊的变量,对于变量使用,我们都是直接使用它的名字,就好象,我们定义个常量 const a=7; 我们要调用它的时候直接使用a就可以了,并不需要带上 const 修饰,这里也一样,用指针变量时并不需要带上“*”; 
    (3)而第三种情况中的 *p=a;中的“*”和第二种里面是不同的,这里的“*”是取内容符,与之相反的是取地址符“&”,分析一下,第三种情况中,等号左边是*p表示对指针p取内容,它的内容指向内存中的某个已经在开始通过 int *p; 定义好的空间里(比较确切一点的说法是,p在定义的时候,其内容里的地址指向内存中某个未知的空白区域,即未占用,不受保护的内存空间),这个空间里存放的数据类型是整型,所以等号的右边也应该是整型才能匹配,所以是 *p=a; 这里的“*”和定义时候的是不同的,这一点很重要。 

  其实上面的都是些题外话,我要说的其实是关于指针的输出的一些问题。我们利用上面定义好的进行输出操作。 

  输出指针的内容(即所指向空间的地址):cout<<p<<endl; 
  输出指针所指的内容(即指针内容所描述地址空间中的内容):cout<<*p<<endl; 

  指针对于字符的处理却有些特殊,和前面的非字符的指针输出处理要分开理解。 

  比如,我们定义一个 char a='A'; char *p=&a;  如果我们调用上面非字符指针的输出方式,结果如下: 
  方式1 cout<<p<<endl; 结果 A####(#表示乱码,不可识别) 并不是地址 
  方式2 cout<<*p<<endl; 结果 A 这和非字符的指针情况一样,输出指针指向的内容 
  而且我们直接操作 cout<<&a<<endl; 结果和方式1的结果是完全相同的 

  为什么方式1输出的不是地址呢?这里有一个特殊的处理,虽然这里的p的内容确确实实是一个地址,但是cout操作字符指针的话,它遇到地址,就会直接去寻找这个地址所指向的内容,并把它的空间里的机器数按照字符的规则转化成字符输出,直到遇到“\0”这个操作符才停止。所以我们直接输出p的时候,它先输出‘A’然后再继续读取后面的内存空间知道遇到“\0”,显示结果是“A+乱码”。 

  你肯定会说,为什么要这样呢,这样多不方便呀,其实这么做是有目的的,而且恰恰就是为了方便才这么设置的。因为这样就可以很容易的处理字符串了,而处理字符串是我们在计算机中用得很多的操作。 

  比如我们第一个字符串数组 char a[]="mantou"; a[]在内存中在7个字节,而不是6个,因为在mantou字符串后面还隐藏有一个“\0”,这时我们用 char *p=a; (这里不用&a是因为,a[]是一个数组,数组名a本身就是一个指针常量) 输出操作 cout<<p<<endl; 这里就不会输出地址,而是直接输出整个mantou字符串,很方便哈,如果我们 cout<<*p<<endl; 结果显示的是m,因为p是指向数组的首元素的地址的,就是指向这里的储存m的空间的地址,所以取p的内容(*p),只能输出一个m哦。 

  虽然通常情况下我们是不需要了解我们的数据地址的,但我也顺便说说,怎么得到字符指针的地址,也可以方便大家对内存地址的分配再做更深入的研究。 

  char a='A';  如果这里直接输出 cout<<&a<<endl; 当然是不能输出地址的,原理上面已经说过了,cout遇到字符型地址就会转换成字符串输出。我们可以用指针p先取得a的地址(char *p=&a;),但是这样用 cout<<p<<endl;也并不能得到地址呀,原因上面也说过了。 
    做个小技巧,首先我们知道p中的内容本身就是地址,但是因为它是字符串,我们又不能直接输出它,所以呀,我们可以把指针里的内容(记载的是一个地址数据)强制转化成整型再输出 cout<<(int)p<<endl; 呵呵,这样就得到了这个指针里的内容——十进制型的地址,而我们知道,地址是用十六进制表示的,形式是 0x######## 0x后面加8位十六进制数,我们把我们先得到的十进制地址按照地址的表示形式用流操作转化成十六进制就可以了。代码如下: 
cout<<endl<<"0x" 
     <<setw(8)<<setiosflags(ios::right)<<setfill('0') 
     <<setiosflags(ios::uppercase)<<hex<<(int)p<<endl; 

注意不要忘了 #include<iomanip.h> 这个头文件哦  

C++ 中,字符指针(`char*`)常用于处理字符串。字符指针指向字符数组的首地址,可以用于访问和操作字符串内容。以下是几种常见的字符指针使用方法: ### 1. 指向字符串常量 字符指针可以直接指向一个字符串常量,此时字符串存储在只读内存区域,不能通过指针修改字符串内容。 ```cpp const char* ptr = "Hello, World!"; std::cout << ptr << std::endl; // 输出:Hello, World! ``` ### 2. 指向字符数组 字符指针也可以指向一个字符数组,数组中的字符串可以被修改。 ```cpp char str[] = "C++ Programming"; char* ptr = str; std::cout << ptr << std::endl; // 输出:C++ Programming ptr[4] = '-'; // 修改字符串内容 std::cout << ptr << std::endl; // 输出:C++-Programming ``` ### 3. 动态分配内存 使用 `new` 或 `malloc` 动态分配内存,适用于运行时确定字符串长度的情况。 ```cpp char* ptr = new char[50]; strcpy(ptr, "Dynamic Memory Allocation"); std::cout << ptr << std::endl; // 输出:Dynamic Memory Allocation delete[] ptr; // 释放内存 ``` ### 4. 指针算术操作 字符指针支持指针算术操作,可用于访问字符串中的子串或特定字符。 ```cpp char str[] = "C++ Programming"; char* ptr = str; std::cout << ptr + 4 << std::endl; // 输出:Programming ``` ### 5. 使用 `const` 限制修改 如果字符串不应被修改,可以使用 `const char*` 限制指针的写操作。 ```cpp const char* ptr = "Read-Only String"; // ptr[0] = 'r'; // 错误:尝试修改常量字符串会导致未定义行为 ``` ### 6. 多级指针字符串数组 字符指针数组可用于存储多个字符串,适用于字符串列表的管理。 ```cpp const char* languages[] = {"C", "C++", "Java", "Python"}; for (int i = 0; i < 4; ++i) { std::cout << languages[i] << std::endl; } ``` ### 7. 字符指针与函数 字符指针可以作为函数参数传递,用于处理字符串操作。 ```cpp void printString(const char* str) { std::cout << str << std::endl; } int main() { const char* message = "Function Argument"; printString(message); // 输出:Function Argument return 0; } ``` 字符指针的使用需要特别注意内存管理,确保指针不越界、不悬空,并在动态分配内存后及时释放[^2]。 --- ###
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值