c++ 踩坑大法好 char字符,char数组,char*

c++ 踩坑大法好 char字符,char数组,char*

1,基本语法

1,定义一个char字符:

char hehe='a';

//单引号

2,定义一个由char字符组成的数组:

char daqing[] = "abcd";

char daqing[] = { 'a','b','c','d' };

//两个效果一样,这两个都是和字符相关的实体,不是指针,但是因为是数组,数组的取值规则是,存储第一个元素的地址,依次向后遍历直到找到\0,所以,daqing这个变量是地址(尽管存储的是地址,但是daqing不是指针类型,是实体),它指向字符a,取值的时候直接取daqing[0]

如何遍历这两个char数组?

方法一,直接按照下标拿值

for (int k = 0; k < sizeof(daqing);k++) {

printf("address---> %c \n", daqing[k]);

}

方法二,按地址拿值

char * test = &daqing[0];

//先定义一个指向头的指针,指针内容是第一个元素的地址

for (int k = 0; k < sizeof(daqing);k++) {

printf("address--->*test---> %c \n", *test);

test++;

}

//*test的意思的把地址翻译为内容,test++表示拿下一个挨着的地址

3,定义char*

话说,char*是个啥,如果写char * hehe="abc";有些环境要这么写才行(const char * hehe="abc";)表示定义一个char指针名字叫hehe,hehe指向静态文本区(就是const静态区)数组的“abc"的首地址,因为是静态区,所以,如果你后期想把”abc“改成”cba“,抱歉,那不可以!除非你重新把hehe指向”cba",此时之前创建的"abc"貌似是还没有销毁,得等到程序执行完毕以后由系统回收。听起来用途也不大广泛的样子。不过还是说一下。

const char* hehe = "abc";

//定义一个指针指向静态区的“abc"的头一个元素的a的地址,这个用法还是少用点

const char* str[] = { "Hello", "C++", "World" };

//这个就比较厉害了,这个和上一个不一样,这个是定义了一个数组,数组的元素是指向静态区的指针,相当于把好多个hehe放到了一个数组中

如何遍历:

for (int j = 0; j < 3;j++) {

printf("value %c ",str[j]);

}

虽然要慎用,但是也不是说一点用也没有,个人目测,int main(int argc, char *argv[]) {...}里面的argv就是指针数组这样的结构,argv第0个参数是程序名,argc是参数的个数。

看一个把char* str[]当作参数传递的例子,argv也可以这么用:

#include

using namespace std;

void test(char *xc[]);

//形参声明了这是一个内含一堆char指针的数组

int main() {

char *hehe[] = { "abc","bcd" };

test(hehe);

return 0;

}

void test(char *xc[]) {

cout << xc[0] << endl;

}

让值得注意的是,

#include

using namespace std;

int main() {

//定义一个指针指向单个字符,如下写法是正确的:

char t2='2';

char *t22 = &t2;

//但是这样的写法是报错的:

char *t22 = 'a';

//虽然char指针不能指向单个字符,却可以指向char数组,奇了怪了

char *t3 = "abc";

return 0;

}

后来查阅了一下,双引号“abc”做了三件事:1,申请了空间(在常量区),存放了字符串 ;2. 在字符串尾加上了'/0' ;3.返回地址;

所以说char *t3=“abc”的时候,t3就有了地址,但是‘a'存在于内存中只是一串ascii码,没有被储存起来,没有地址。所以不能直接赋值。

尽管这样语法是正确的,但是这样的写法很诡异,为什么很诡异,看例子

const char *aa = "123";

//定义一个char字符(不是数组)的指针,指向一个静态区的一个char数组的第一个元素

printf("%p,%p\n", aa,"123");

//验证一下,aa确实是地址,并且和“123”地址一模一样

cout <<*aa << endl;

//char数组用cout打印一般能打印出来全部的元素,但是*aa不行,只能打印出1来,因为我们是用char字符的指针存储了char数组的地址,感觉上就不大常用

就好比:

aa是const char * 指针,指向地址0x11,0x11上放了一个字符“a",不管其他地址上是什么,我char字符只拿0x11上一个字节的内容。

bb是const char * 指针,指向地址0x20,0x20上放了字符“d",0x21上放了字符“e",0x22上放了字符“f",0x23上放了字符“\0",我如果按照char 指针的规则来拿,我只能拿到”d",但是我如果按照char数组的规则来拿,先拿到了”d”,又拿到了“e","f",遇到\0停止了,所以我能拿到def。

2,顺带说一声c++的存储区

一个由c/C++编译的程序占用的内存分为以下几个部分,感谢原作者1、栈区(stack)—由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于

数据结构中的栈。2、堆区(heap)—一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。注意它与数据

结构中的堆是两回事,分配方式倒是类似于链表,呵呵。3、全局区(静态区)(static)—全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态

变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后由系统

释放。

个人理解,仅供参考:

int daqing=3; //栈里有个daqing的名字和地址,指向堆里的一个整数3;如果是在main上面,那就是全局初始化区(静态区)

int b; //main下的,栈区

char *p2; //栈

static int c=0; //全局(静态)初始化区

char *p2; //栈

p2 = (char*)malloc(20); //分配得来得20字节的区域就在堆区。

3,补充,char数组和char字符不一样

区别:

char hehe[]="ab";

printf("%p,%p\n", hehe,&hehe[0]);

//hehe打印出来是数组中第一个元素的内存地址,, hehe和hehe[0]地址一样,所以使用char数组的时候要注意,即使不加&,它本身就是地址,类似于指针

char aa='a';

//aa存储的是字符“a”,和int是一个道理,aa不是指针,是个值

拿传递参数来说明使用char和char数组的区别:

char

using namespace std;

int test(char *xc);

int main() {

char t2='2';

test(&t2);

//此处相当于int *xc=&t2;int型指针xc这个变量现在指向的是t2的地址

printf("quanju %c\n", t2);//打印为:2

return 0;

}

int test(char *xc) {

char t1 = '1';

*xc = t1;

//*xc是个值,*t1也是个值,通过修改xc指向的内存的值,也修改了外部变量

cout << *xc << endl;

printf("jubu %c\n",*xc);

return 0;

}

char数组

#include

using namespace std;

int test(char *xc);

int main() {

char t2[]="2";

test(t2);

//此处相当于int *xc=t2(t2本身就是指向它第一个元素的地址);int型指针xc这个变量现在指向的是t2的地址

printf("quanju %c\n", t2[0]);//打印为:2

return 0;

}

int test(char *xc) {char t1[] = "1";

*xc = *t1;

//*xc是个值,*t1也是个值,通过修改xc指向的内存的值,也修改了外部变量

printf("jubu %c\n",xc[0]);

return 0;

}

相关推荐

硬盘盘片划伤详解,划伤种类与识别方法
365平台是做什么的

硬盘盘片划伤详解,划伤种类与识别方法

📅 08-22 👁️ 7463
基本字义解释
365平台是做什么的

基本字义解释

📅 07-23 👁️ 5344
性转换漫画
365bet365打不开

性转换漫画

📅 07-31 👁️ 3002
三国战记貂蝉那里的门怎么打开(三国战纪手游解说貂蝉)
猎人手册丨看完这些或许你对狩猎会有其他的想法!
365平台是做什么的

猎人手册丨看完这些或许你对狩猎会有其他的想法!

📅 07-24 👁️ 8385
长虹电视显示蓝屏
365平台是做什么的

长虹电视显示蓝屏

📅 08-09 👁️ 7343
为什么要继续坚持戴口罩?
365BET娱乐场下载

为什么要继续坚持戴口罩?

📅 07-27 👁️ 1082
双子座的优点是什么
365平台是做什么的

双子座的优点是什么

📅 06-29 👁️ 790
看影网-好看的电影
365BET娱乐场下载

看影网-好看的电影

📅 07-14 👁️ 3191