C++ 字符、字符串、字符数组、字符串指针、指针数组

一、字符指针、字符数组

字符指针

字符串指针变量本身是一个变量,用于存放字符串的首地址。而字符串本身是存放在以该首地址为首的一块连续的内存空间中并以 作为串的结束。

char *ps="C Language";

顺序是:1.分配内存给字符指针;2.分配内存给字符串;3.将字符串首地址赋值给字符指针;

char *ps;  // ps 字符串指针,是指针,是一个变量

ps=”C Language”; // ps 为字符串的首地址,利用 ps++ 可遍历字符串,字符串存储在以 ps 为开始地址的地段连续的内存空间中,并以 作为字符串的结束。

这里有两点需要考虑清楚的地方:

1、*a 只是指向一个字符。

举例如下:

实例

#include stdio.h>
#include stdlib.h>

int main(void){
char *a= bcd ;
printf(输出字符:%c n, *a); /*输出字符,使用”%c”*/
printf(输出字符:%c n, *(a+1) ); /*输出字符,使用”%c”*/
printf(输出字符串:%s n, a); /*输出字符串,使用”%s”;而且a之前不能有星号”*” */
system(pause); /*为了能看到输出结果*/
}

运行结果如下:

输出字符:b 
输出字符:c 
输出字符串:bcd 

2、若字符串常量出现在在表达式中,代表的值为该字符串常量的第一个字符的地址。所以 hello 仅仅代表的是其地址。原声明方式相当于以下声明方式:

char *a;  
a="hello"; /*这里字符串"hello"仅仅代表其第一个字符的地址*/

字符数组

字符数组是由于若干个数组元素组成的,它可用来存放整个字符串。(即用字符数组来存放字符串)。

在 C 语言中,将字符串作为字符数组来处理。(C++中不是)

字符数组初始化的方法:

1). 可以用字符串常量来初始化字符数组:

char  str[]={"Iamhappy"};

可以省略花括号

char  str[]="Iamhappy";  # 系统自动加入  

注意:上述这种字符数组的整体赋值只能在字符数组初始化时使用,不能用于字符数组的赋值,字符数组的赋值只能对其元素一一赋值。

下面的赋值方法是错误的:

char str[20];
str="Iamhappy";

对字符数组的各元素逐个赋值。

char str[10]={'I','','a','m','','h','a','p','p','y'};

在 C 语言中,可以用两种方法表示和存放字符串:

(1)用字符数组存放一个字符串

char str[]="IloveChina";

(2)用字符指针指向一个字符串

char *str="IloveChina";

两种表示方式的字符串输出都用:printf(”%sn”, str);

%s 表示输出一个字符串,给出字符指针变量名 str(对于第一种表示方法,字符数组名即是字符数组的首地址,与第二种中的指针意义是一致的),则系统先输出它所指向的一个字符数据,然后自动使 str 自动加 1,使之指向下一个字符…,如此,直到遇到字符串结束标识符


二、字符串指针

string* str 可以赋值:

string* str = {"hello", "world"}; 
//  对比与 char *name = "wang" = {'w','a','n','g'}
//  *(str) = "hello", *(str+1) = "world"
//  *(*(str)+1) = 'e'

也就是说每个元素都是 string 类型的,跟 char* 是不一样的,不过 string* 可以用 char** 来代替:

string = char*, string* = char**

三、(字符串)指针数组

实例

#include stdio.h>
void main()
{
char *str[] = {Hello, C++, World}; //char (*str)[] = …
int i;
for(i=0; i3; i++)
printf(%sn, str[i]);
}
// str[0]字符串”hello”的首地址,str[0]+1:字符串”hello”第二个字符’e’的地址,str[2]=str+2:第三个字符串”world”的首地址
// str[1]字符串”C++”的首地址
// str[2]字符串”world”的首地址

实例

#include stdio.h>
#include string.h>
int main()
{
char *str[] = {Hello, C++, World};
char **p;
for(p=str; pstr+3; p++)
puts(*p); #*p为字符串首地址,*p[0]为字符串的第一个字符地址
}

实例

#includestdio.h>
#includestdlib.h>
int main()
{
char *str[3]={Hello,C++,World};
printf(%s,%s,%c,str[0],str[0]+1,*(*(str+2)+1));
system(pause);
}

结果为:

Hello,ello,o

格式:char* na[N] = {“li”, “zh”, “li”, “zh”, “li”};

char *a[]:表示a是数组,数组中的元素是指针,指向char类型,(数组里面所有的元素是连续的内存存放的)
数组名是数组第一个字节的内存地址,并且数组名a也表示指针。所以a 并不表示a地址存储的内容, 而是a地址本身。

a+1:表示 a 的第二个元素的内存地址, 所以是加 8 字节。( 因为a的元素是char 指针, 所需要的空间为8字节(64位内存地址)。 )

*(a+1):则表示a这个数组的第二个元素的内容 (是个char 类型的指针,本例表示为world字符串的地址)。

*(*(a+1)):则表示a这个数组的第二个元素的内容(char指针)所指向的内容(w字符).

char * a[10]:表示限定这个数组最多可存放10个元素(char指针), 也就是说这个数组占用10*8 = 80字节。

#w:        a+1   =>   *(a+1)  =>   *(a+1)[0]
           指针(地址)   指针内容(字符串)      字符

char *argv:理解为字符串
char **argv:理解为字符串指针
char *argv[]:字符串指针数组

int main(int argc, char*argv[])
这是一个典型的数组名(或者说是指针数组)做函数参数的例子,而且还是没有指定大小的形参数组。

有时为了再被调用函数中处理数组元素的需要,可以另设一个形参,传递需要处理的数组元素的个数。而且用数组名做函数实参时,不是吧数组元素的值传递给形参,而是把实参数组的首元素的地址传递给形参数组,这样两个数组久共同占有同一内存单元。 和变量作函数参数的作用不一样。

可以去看看关于数组作为函数参数和指针数组作main函数形参方面的例子。谭浩强的那本书讲的很细,对这个有详细的解释。

1. 当 char [] 作为函数的参数时, 表示 char *. 当作为函数的参数传入时, 实际上是拷贝了数组的第一个元素的地址。

所以 void test (char a[]) 等同于 void test ( char * a )

 char x[10] ;

然后调用 test(x) 则等同于把 x 的第一个元素的地址赋予给参数 a。

2. char * a 和 char a[]

  • 相同点 : a都是指针, 指向char类型。
  • 不同点 : char a[] 把内容存在stack。char *a 则把指针存在 stack,把内容存在 constants。

3. char * a[10] 和 char a[10][20]

  • 相同点 : a 都是2级指针, *a 表示一级指针, **a 表示内存中存储的内容。
  • 不同点 : char * a[10], 数组由char * 类型的指针组成; char a [10][20] 表示一位放10个元素, 二维放20个元素, 值存放地是一块连续的内存区域, 没有指针。

4. 小窍门 : [] 和 * 的数量对应, 如 char a[][] 的指针层数是 2, 相当于 char **a; char *a[] 也是如此, 两层指针. 迷糊的时候数数到底有几个 * 几个 [], 就知道什么情况下存储的是内容还是地址了 ? 如 char a[][] 的情况里面: &a, a, *a 都是地址, **a 是内容。

原文地址:https://www.cnblogs.com/cj2014/p/3726380.html

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
  1. 免费下载或者VIP会员资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
  2. 提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。 若排除这种情况,可在对应资源底部留言,或联络我们。
  3. 找不到素材资源介绍文章里的示例图片?
    对于会员专享、整站源码、程序插件、网站模板、网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
  4. 付款后无法显示下载地址或者无法查看内容?
    如果您已经成功付款但是网站没有弹出成功提示,请联系站长提供付款信息为您处理
  5. 购买该资源后,可以退款吗?
    源码素材属于虚拟商品,具有可复制性,可传播性,一旦授予,不接受任何形式的退款、换货要求。请您在购买获取之前确认好 是您所需要的资源

评论(0)

提示:请文明发言