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 = ; k < sizeof(daqing);k++) {
printf("address---> %c \n", daqing[k]);
}
方法二,按地址拿值
char * test = &daqing[];
//先定义一个指向头的指针,指针内容是第一个元素的地址
for (int k = ; 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 = ; j < ;j++) {
printf("value %c ",str[j]);
}

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

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

#include <iostream>
using namespace std;
void test(char *xc[]);
//形参声明了这是一个内含一堆char指针的数组
int main() {
char *hehe[] = { "abc","bcd" };
test(hehe);
return ;
}
void test(char *xc[]) {
cout << xc[] << endl;
}

让值得注意的是,

#include <iostream>

using namespace std;

int main() {
//定义一个指针指向单个字符,如下写法是正确的:
char t2='';
char *t22 = &t2;
//但是这样的写法是报错的:
char *t22 = 'a';
//虽然char指针不能指向单个字符,却可以指向char数组,奇了怪了
char *t3 = "abc";
return ;
}

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

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

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

    const char *aa = "";
//定义一个char字符(不是数组)的指针,指向一个静态区的一个char数组的第一个元素
printf("%p,%p\n", aa,"");
//验证一下,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[]);
//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='';
test(&t2);
//此处相当于int *xc=&t2;int型指针xc这个变量现在指向的是t2的地址
printf("quanju %c\n", t2);//打印为:2
return ;
}
int test(char *xc) {
char t1 = '';
*xc = t1;
//*xc是个值,*t1也是个值,通过修改xc指向的内存的值,也修改了外部变量
cout << *xc << endl;
printf("jubu %c\n",*xc);
return ;
}

char数组

#include <iostream>
using namespace std;
int test(char *xc);
int main() {
char t2[]="";
test(t2);
//此处相当于int *xc=t2(t2本身就是指向它第一个元素的地址);int型指针xc这个变量现在指向的是t2的地址
printf("quanju %c\n", t2[]);//打印为:2
return ;
}
int test(char *xc) {char t1[] = "";
*xc = *t1;
//*xc是个值,*t1也是个值,通过修改xc指向的内存的值,也修改了外部变量
printf("jubu %c\n",xc[]);
return ;
}

c++ 踩坑大法好 char字符,char数组,char*的更多相关文章

  1. c++踩坑大法好 typedef和模板

    1,typedef字面意思,自定义一种数据类型 语法:typedef 类型名称 类型标识符; 基本用法: 1) 为基本数据类型定义新的类型名. 2) 为自定义数据类型(结构体.公用体和枚举类型)定义简 ...

  2. c++ 踩坑大法好 枚举

    1,枚举是个啥? c++允许程序员创建自己的数据类型,枚举数据类型是程序员自定义的一种数据类型,其值是一组命名整数常量. ,wed,thu,fri,sat,sun}; //定义一个叫day的数据类型, ...

  3. c++踩坑大法好 数组

    1,c++遍历数组 int数组和char数组不同哦,int占4位,char占1未,同理double也不同.基本遍历方法: ] = { ,,, }; ]); printf("len of my ...

  4. c++踩坑大法好 赋值和指针的区别

    1,先说结论: 两个指针指向同一个结构,一个改了结构,另一个也会改掉. 两个指针指向同一个结构,修改了其中一个的指向,并且改了其中的内容,另一个不为所动. 2,看例子 main.cpp #includ ...

  5. c++ 踩坑大法好 复合数据类型------vector

    1,vector是啥? 是具有动态大小的数组,具有顺序.能够存放各种类型的对象.相比于固定长度的数组,运行效率稍微低一些,不过很方便. 2,咋用? 声明: vector <int> vi; ...

  6. c++踩坑大法好 宏定义 头文件

    1,c++宏定义是干啥的?防止重复引用,如何防止重复引用? //a.h //声明一个类,和其他声明 #include <iostream> class A{ public: static ...

  7. Java 开发中如何正确踩坑

    为什么说一个好的员工能顶 100 个普通员工 我们的做法是,要用最好的人.我一直都认为研发本身是很有创造性的,如果人不放松,或不够聪明,都很难做得好.你要找到最好的人,一个好的工程师不是顶10个,是顶 ...

  8. 《挑战30天C++入门极限》C/C++中字符指针数组及指向指针的指针的含义

        C/C++中字符指针数组及指向指针的指针的含义 就指向指针的指针,很早以前在说指针的时候说过,但后来发现很多人还是比较难以理解,这一次我们再次仔细说一说指向指针的指针. 先看下面的代码,注意看 ...

  9. 字符数组char

     数组做sizeof的参数不退化,传递给strlen就退化为指针: #include<stdio.h> #include<stdlib.h> #include<strin ...

随机推荐

  1. 流程图GGEditor 之 自定义节点相关属性

    自定义节点 注册 -- registerNode 我们通过以下接口往 G6 全局注册节点: // 注册节点 G6.registerNode(name, { // 绘制 draw(item) {   r ...

  2. centos安装gitlab及汉化

    GitLab 是一个用于仓库管理系统的开源项目,使用Git作为代码管理工具,并在此基础上搭建起来的web服务.今天,就记录一下centos部署gitlab及其汉化的操作方法. 1.下载安装 下载地址: ...

  3. ora.vip 1 ONLINE INTERMEDIAT

    问题出现情景: 三节点12C rac某次扩存储,两个节点同时重启,其中一个节点 ora.rac1.vip 1 ONLINE INTERMEDIATE rac2 FAILED OVER   出现原因可能 ...

  4. 图片中添加箭头【使用PPT实现】

    手头上可以使用的方案 QQ截图 分辨率会改变 画图 网上的教程一般是画一根线再加一个三角来画箭头,有点麻烦,改起来不好改. PS 对我来说,软件安装本身就是个问题, 插入图片,加入箭头,组合,另存为, ...

  5. C#面向对象详解

    //封装就是将数据或函数等集合在一个个的单元中,我们称之为类,被封装的对象通常被称为抽象数据类型, //封装的意义在于保护或防止代码被我们无意中破坏, //封装既可以封装成员变量,又可以封装成员方法, ...

  6. #6499. 「雅礼集训 2018 Day2」颜色 [分块,倍增,bitset]

    bitset压位,因为是颜色数,直接倍增,重合部分不管,没了. // powered by c++11 // by Isaunoya #include <bits/stdc++.h> #d ...

  7. ABP前端-关于不同按钮调用同一事件传入的参数变为相同的数据

    现象: 在一个含有的Tab标签的页面,两个标签页的新增按钮调用同一个新增事件并传入不同的参数,但实际在调用的的时候传入的参数都变成了最后一个按钮传入的值,即,不论点击哪个Tab按钮的新增事件,最终传入 ...

  8. Centos 7 firewall的防火墙的规则

    这是官方文档: http://www.firewalld.org/documentation/man-pages/firewall-cmd.html 想使用iptables的规则,firewall也可 ...

  9. Rtudio 安装包报错

    今天重新安装了一下Rstudio,基本上很多包都安装不上,问了度娘发现被墙了 f..k.. 解决办法,更改安装包的镜像为清华镜像 tools->gloabl options->packag ...

  10. Truck History POJ - 1789 板子题

    #include<iostream> #include<cstring> #include<algorithm> #include<stdio.h> u ...