问题的引入:
char a[]=" abc " ;
char b[]=" abc " ;
char *c=" abc " ;
char *d=" abc " ;
const char e[]=" abc " ;
const char f[]=" abc " ;
const char *g=" abc " ;
const char *h=" abc " ;
printf(" %i\n " ,a==b);
printf(" %i\n " ,c==d);
printf(" %i\n " ,e==f);
printf(" %i\n " ,g==h);
正确的答案:0 1 0 1。
说明:指针不分配所指向的数据的空间,数组分配所有元素的内存空间。
char *c="abc"; 这是定义一个指针,并把常量区的一个字符串“abc”的首地址赋值给这个指针,所以,是无法修改数据
内容的(*p='h',错!),但是可以修改指针,如c=a;
char a[]="abc";这是定义一个数组,然后把常量区字符串"abc"拷贝到这个数组中来(数组分配所有元素的内存空间)。所
以操作和常量区的“abc”没有关联,故可以赋值:a[0]='d',OK.但是不能修改a,如a=c错,a就像是const属性的指针。
a与b,e与f的地址是不同的所以a==b为0,e==f为0.但是c与d,g与h的都是指向同一个常量区的地址,所以相等。
其中,strlen(a)=strlen(c)=3;sizeof(a)=4,sizeof(c)=4;sizeof(c)=4是因为c是指针,指针的sizeof是一个定值为4.
const char *str=“abcd”与char *str=“abcd”的区别
1.浅白一点:前者如果修改某个字符(str[1]='x')的时候在编译时就会报错,二后者在运行时报错。两者都不允许这种修改。前者在编译时报错是因为限制符const的作用。后者是因为''abcd'在常量区,str只是指向常量区的地址的指针,没法进行修改。
2.char p[]="1234";
const char* str="abcd";
str=p;
str[2]='1';//非法
str变成指向数组p的指针,数组名表示地址。但是有const char限制,指针是没法修改数组内容的(数组的内容都在栈区)。
如果:char* str="abcd";
str=p;
str[2]='1';//合法。 数组及其元素在栈区是云寻修改的。
char *与char[]的区别:
问题引入:
char *c="abc" 和char c[]="abc"前者改变其内容程序会崩溃,后者完全正确。
代码:
#include<iostream>
using namespace std;
main()
{
char *c1 = "abc";
char c2[] = "abc";
char *c3 = ( char* )malloc(3);
c3 = "abc";
printf("%d %d %s\n",&c1,c1,c1);
printf("%d %d %s\n",&c2,c2,c2);
printf("%d %d %s\n",&c3,c3,c3);
getchar();
}
运行结果
2293628 4199056 abc c1存储的是"abc"在常量区的地址,&c1表示指针的地址,此地址存储在栈区
2293624 2293624 abc c2本身表示的就是地址,所以与&c2是相同的
2293620 4199056 abc &c3表示的指针c3的地址,此地址也是存储在栈区,c3指向的地址存储的内容"abc"在常量区
已经存在,所以c3存储的也是"abc"在常量区的地址与c1是相同的。
同时我们还可一发现有四个地址是在一个区域的,说明这些都存在与栈区。而''abc''存在于常量区。这两个地址还是有意定距离的。
存取效率:
char s1[]="aaaaaaaaaaa";
char *s2="bbbbbbbbbbb";
aaaaaaaaaa是在运行时赋值的。而bbbbbbbbbbb是在编译时就确定的,因为他存在于栈区。但是,在以后的存取过程中,在栈上数组比指针所指向的字符串要快。
总结:
char *c1="abc";实际上先是在文字常量区分配一块内存存放"abc",然后在栈上分配一地址给c1并指向这块地址,然后改变常量"abc"自然会崩溃。
char c2[]="abc";实际上abc分配内存地址的地方在栈区与上面的地址是不同的,是可以修改的。
深入思考:
#include <iostream>
using namespace std;
main()
{
char *c1 = "abc";
char c2[] = "abc";
char *c3 = ( char* )malloc(3); //分配来的3个字节在堆区
// *c3 = "abc" //error ==>报错:不能将const char* 类型的值分配给char 类型的实体,所以必须
c3=“abc”,两边都是char*类型
strcpy(c3,"abc"); ==>把第二个参数含有NULL的字符串赋值到以c3开始的地址空间,并且两个参数所指的内存区域不
可以重叠
c3[0] = 'g';
//c3="abc";c3[0]='g'; //error==>报错:c3指向的是在常量区的地址,而不是指向自己分配的地址,所以不能修改
printf("%d %d %s\n",&c1,c1,c1);
printf("%d %d %s\n",&c2,c2,c2);
printf("%d %d %s\n",&c3,c3,c3);
getchar();
}
输出:
2293628 4199056 abc
2293624 2293624 abc
2293620 4012976 gbc 可以看到c1存储的地址与c3存储的地址是不同的。
实例:
char* get_str(void)
{
char str[] = {"abcd"};
return str;
}
char str[] = {"abcd"};定义了一个局部字符数组,尽管是数组,但它是一个局部变量,返回它的地址肯定是一个已经释放了的空间的地址。
此函数返回的是内部一个局部字符数组str的地址,且函数调用完毕后 此数组被销毁,所以你返回的指针也就指向一块被销毁的内存,这种写法是错误的
char* get_str(void)
{
char *str = {"abcd"};
return str;
}
char* str = {"abcd"};表示先定义个字符串常量,并将其地址赋给str。
此函数返回的是字符串常量的地址,而像这种字符串都是属于全局的,在编译的时候就已经分配了内存了,只有程序退出的时候才会被销毁,所以返回它的地址是没有问题的,但是你最好返回常量指针,因为你不能去改变字符串常量的值。
这个str就在栈里面,但后面的字符串在常量区,函数返回的时候,先将常量区的地址返回,然后作用域结束,释放str在栈里面的空间。
准确的说,上面两个“abc"都是存储在静态存储区,即常量区,存储在堆上
。常量区是可读不可写的。
所以任何试图对常量区进行写的操作都是非法的,当然了,这也不是一定不可写的,你可以采取某种渠道改变常量区的内存属性,比如改变pe相关节的属性就可以
对常量区进行读写,当然了,这个目前可以忽略。
那么为什么str[] = "abc"; 可以写呢? 答案就在str[] = "abc";会有一个额外的拷贝过程,即把常量区的 "abc"拷贝到栈内存去,所以就可以写了。
C风格字符串与string的区别与联系:
C:字符串一般存储在一个字符数组中,通过一个char* 类型的指针来操纵它
常用的字符串函数:字符串不包含\0的长度:int strlen(const char*)
两字符串是否相等:int strcmp(const char*, const char*)
将第二个字符串拷贝到第一个字符串中:char* strcpy(char*, const char*)
相关的头文件:#include<cstring>
操作实例:const char *st=“this is a dog”;系统在内部把字符串常量存储在一个字符串数组中,然后让st指向该数组的第一个元素。操作手段一般是while(*st++){.....};
例如: int string_length(const char* st){
int cnt=0;
if(st){
while(*st++)
__cnt;
}
return cnt;
}
string类型:头文件 #include<string> string st(“this is a dog”)
st.size()返回的长度不包括终止空字符
用0一个string初始化另一个string对象:string st3(st);
比较两个string对象用==:两者相等返回true,否则返回false===>if(str1==str2)
拷贝一个字符串用=:str2=str1;
连接两个字符串用+:string st3=st2+st1;或者st2+=st1;
混合使用C风格的字符串以及string对象:
const char* pc=",";
string s1("hello");
string s2("world");
string s3=s1+pc+s2+"\n"; 机理:string类型能够自动将C风格的字符串转换成string对象
可以将C风格的字符串赋值给一个string对象:
string s1;
const char *pc="this is a dog";
s1=pc;
但是反向的string向C风格的字符串的转换不是自动的,必须显式的调用c_str():
char *str=s1; //错误
char *str=s1.c_str(); //几乎正确 字面意思表示:指向字符数组起始处的字符指针
为了防止字符数组被程序直接处理,c_str()返回了一个指向常量数组的指针
const char* str=s1.c_str(); //正确
string类型支持下标操作访问单个字符。
例如:string str("fa.disney.com");
int size=str.size();
for(int ix=0;ix<size;i++){
if(str[ix]=='.')
str[ix]='_';
}
发表评论
-
析构函数为虚函数的原因
2012-09-09 11:42 831我们知道,用C++开发的时候,用来做基类的类的析构函数 ... -
hash的应用
2012-08-31 23:02 961第一部分为一道百度面试题Top K算法的详解;第二部分为关 ... -
微软智力题
2012-08-29 19:59 566第一组1.烧一根不均匀的绳,从头烧到尾总共需要1个小时。现在有 ... -
C++不能被继承的类
2012-08-27 20:16 1058一个类不能被继承, ... -
括号对齐问题
2012-08-27 10:47 1409解法一:左右括号成一对则抵消 可以 ... -
树的遍历
2012-08-19 10:43 719/****************************** ... -
堆排序
2012-08-16 14:24 882堆:(二叉)堆数据结构是一种数组对象。它可以被视为一棵完全 ... -
多态赋值
2012-08-14 16:16 830#include <iostream> usi ... -
static变量与static函数(转)
2012-08-13 10:15 746一、 static 变量 static变量大致分为三种用法 ... -
不用sizeof判断16位32位
2012-08-10 15:21 1703用C++写个程序,如何判断一个操作系统是16位还是3 ... -
找出连续最长的数字串(百度面试)
2012-08-09 15:15 1146int maxContinuNum(const char*in ... -
顺序栈和链栈
2012-08-06 10:01 798顺序栈:话不多说直接上代码 #include ... -
队列的数组实现和链表实现
2012-08-05 16:20 1024话不多少,数组实现上代码: #include<i ... -
KMP算法详解
2012-08-02 21:40 886KMP算法: 是在一个“主文本字符串” ... -
字符串的最长连续重复子串
2012-08-01 15:05 9776两种方法: 循环两次寻找最长的子串: <方法一> ... -
寻找一个字符串连续出现最多的子串的方法(转)
2012-07-31 21:19 986算法描述首先获得后缀数组,然后1.第一行第一个字符a,与第二行 ... -
字符串的循环移位
2012-07-31 16:52 974假设字符串:abcdefg 左循环两位:cdefgab 右 ... -
一次谷歌面试趣事(转)
2012-07-31 15:26 766很多年前我进入硅谷 ... -
约瑟夫环问题(循环链表)
2012-07-30 21:31 1290题目描述:n只猴子要选大王,选举方法如下:所有猴子按 1, ... -
面试之单链表
2012-07-30 20:18 7271、编程实现一个单链表的建立/测长/打印。 ...
相关推荐
string 和 char* 的区别和联系 在 C++ 编程中,字符串是一种常用的数据类型,string、CString 和 char*都是字符串的 представители,每种类型都有其特点和使用场景。下面我们将详细介绍 string、...
std::string、char*、const char*转托管byte数组或托管字符串String std::string、char*、const char*是C++中三个不同的字符串表示方式,它们都可以转换为托管的byte数组或字符串String,但是在C++/CLI中,它们的...
例如:char *p=string.c_str(); 这里使用了 string 的 c_str() 方法将 string 转换为 const char*,然后将其赋值给 char*。 4. char * 转 string string 可以使用 constructor 将 char* 转换为 string。例如:...
char *p=string.c_str(); 4 char * to string string str(char*); 5 CString to char * strcpy(char,CString,sizeof(char)); 6 char * to CString CString.format("%s",char*); CString的format方法是非常好用的。...
此为QString无损转char*和unsigned char* 。 当QString内容包含汉字时,转换char*等会发生失败。此接口解决了该问题。使用后char*与unsigned char*的qDebug()输出与QString输出结果相同。 注意,该函数返回unsigned ...
CString、int、string、char* 是四种常用的数据类型,在 VC 中它们之间的转换非常常见,本文将详细介绍它们之间的转换方法以及应用实例。 string 转 CString 使用 CString::Format 函数可以将 string 转换为 ...
golang调用c++DLL返回值为char*参数为const char*,读取返回DLL返回值,传递char*型参数
Serialize1(TreeNode *root) 其函数返回类型为char*,但是我在实现的过程中为了更方便的操作添加字符串使用的是C++中string类型的变量,这就导致我最后得到的结果res是string类型,若是要返回需要转化为char *类型...
### cstring、string、char* 的对比、使用与相互转换 #### 一、概述 `string` 和 `CString` 均为字符串处理类,分别适用于不同的编程环境和框架。 - **string**: 属于标准模板库 (STL) 定义的字符串类,广泛应用...
char *p = (LPSTR)(LPCTSTR)cstr; 这段代码将 CString 对象 cstr 转换成 char* 类型的指针 p。 char* 转 CString: char *p; CString cstr; cstr = p; 这段代码将 char* 类型的指针 p 转换成 CString 对象 cstr...
综上所述,`char*` 转换为 `LPCWSTR` 主要有三种方法:使用 `MultiByteToWideChar` 函数、直接定义宽字符字符串以及使用 `_T` 宏。每种方法都有其适用场景和优缺点,开发者可以根据具体需求选择合适的方法。
在本文中,我们将详细介绍 CString、string、char* 之间的转化关系,以及它们之间的比较、运算符重载、常用算法等知识点。 一、CString、string、char* 之间的比较 CString、string 和 char* 都是字符串模板类,但...
在C语言中,合并多个`char *`类型的字符串是一项常见的任务,这通常涉及到字符串操作和内存管理。在给定的场景中,`main.c`文件是测试程序,它调用了`tools.h`头文件中定义的`MultiCombine`函数,这个函数的目的是将...
在探讨字符串处理的过程中,我们经常会遇到不同的数据类型之间的转换问题,尤其是在C++中,常见的有`char *`、`std::string`等不同形式的字符串表示。本篇将重点讨论如何利用`std::string`进行数据类型转换,并分析...
dd(char*d) { P = new char[256]; strcpy(P, d); } // 拷贝构造函数 dd(dd&d) { P = new char[256]; strcpy(P, d.P); } // 析构函数,释放P指向的内存 ~dd() { delete[] P; P = nullptr; } // 获取P指针...
能够按照格式化输出字符串数据,长度不受限制,亲测十几兆都正常。 #include <string> using namespace std;
std::string str(const_char_ptr); std::wstring wstr(str.begin(), str.end()); LPCWSTR wide_ptr = wstr.c_str(); // 现在,wide_ptr是一个LPCWSTR,可以传递给Windows API ``` 这种方法假设输入的`const ...
char* reverseString(char* s) { //将q指向字符串最后一个字符 char* q = s ; while( *q ) { q++; } q -= 1 ; //分配空间,存储逆序后的字符串。 char* p = (char*)malloc(sizeof(char*)*(q-s+1)); ...
一、QString赋值给char*...二 、char [] 赋值给string char str[32]; string str2(str);//这样便把str中的值传给了str2 三 、char* 赋值给QString 例如:char *str1; QString str2; str2 += str1;//这样便把s