当前位置:文档之家› C,C++字符串和字符数组的本质

C,C++字符串和字符数组的本质

C,C++字符串和字符数组的本质
C,C++字符串和字符数组的本质

1、常量字符串

在代码里直接出现的”abcdef”这种字符串,在程序执行的时候,系统会将它们放在常量区,所谓常量区就是一直存在的,只读的,不可更改的数据区域,并且一个字符串只会有一份。假设你在程序里有两行代码

char* p1 = “agcd” ;

char* p2 = “agcd” ;

无论你这两个行代码隔了多远,如果你想知道p1和p2所指向的字符串在内存中是不是同一个,那答案是肯定的,p1和p2的值完全一样。”agcd”这是一个存在于内存中的常量字符串,它从程序一开始就在那里,一直到程序结束读不会改变。在内存中,”agcd”是以如下

’\0’。在种字符串的名字叫“以空字符为结束标志的字符串”。

char* p1 = “agcd” ;

如果你这时候想改变第一个字符的值,用p[0] =’b’,系统会报一个错,常量字符不能更改。(这里为什么指针可以当数组用,下面再解释)。

2、字符数组

如果你定义一个char a[10],那么系统会“只分配”10个char这么长的内存区域,一个char是一个字节,那么系统会分配十个字节的内存控件,并且将这一片连续的内存空间的首地址赋值给a。也就是说“数组名的值是数组所在内存区域的首地址”换句话说“数组名是一个指针,指向数组第一个值的地址”。

如果你定义一个char a[] = “abcdefg”;这句代码就复杂点了。定义一个数组,数组长度未知,那么系统会根据等号后面的值来“初始化”这个数组,等号后面是什么?前面说过,它是一个常量字符串。在内存中占8个字节,7个字符加上一个结束标志。这时候在内存中就有两个”abcdefg”的字符串了,一个是常量区域的,另一个是根据前者复制了一份的。这句代码的意思就是复制一个常量区域的字符串,将复制后的字符串的首字母的地址赋值给a。也就是说,最后a所指向的内存区域,已经不是常量里的”abcdefg”了,这里为什么要复制一份呢?原因是因为常量是不允许更改的,而数组一般都意味着需要修改,所以就复制了一份数据,放在非常量区域,就可以更改了。下面的测试程序可证明上述结论:char* p1 = "abcdef" ;

char* p2 = "abcdef" ;

char a[]= "abcdef" ;

unsigned long dwP1 = (unsigned long)p1 ;

//32位系统里的指针就是4个字节的整数,这样可以具体查看指针的值。

unsigned long dwP2 = (unsigned long)p2 ;

unsigned long dwA = (unsigned long)a ;

printf("p1的值(32位地址) = 0x%X\n",dwP1);

//%X是打印十六进制,X是大写,x是小写

printf("p2的值(32位地址) = 0x%X\n",dwP2);

printf("a的值(32位地址) = 0x%X\n",dwA);

运行后的截图:

从上面的结果可看出,常量字符串在内存中只有一份。而赋值给数组的时候,系统会拷贝一份。如果我们打印a[6]会是什么结果呢,请注意,字符串只有6个,最高索引是5。

printf("a[6]的值=%d",a[6]);//以整数打印

虽然数组的可用长度是6,但是它第7个位置还是存在的,那就是空字符结束标志。空字符结束标志是必须的,因为很多时候系统并不知道你的字符串有多长。

3、应用

当明白了这些本质后,我们怎么来灵活使用字符数组呢。在实际的编码中,比如从文件里读一段文字出来,假设当前文件中的字符串有20个字母。

第一步读取文件大小。

int fileSize = file.getSize();

第二步,分配缓存。这是动态分配数组。这种用法和java相似。

char* p = new char[fileSize+1] ;//加1是为了后面放’\0’.

第三步,读取

file.read(p,fileSize);//意思是从文件里读取filesize个字节,并且放在p所指向的缓存中第四步,标志结尾

P[fileSize] = ‘\0’; //由于指针指向的是字符串首字母地址,而数组名也是一样的,所以C/C++里指针和数组几乎用法一样。其他语言里不一样。这也是C/C++的魅力所在,够灵活。

这时候的p所指向的就是一片连续的内存控件,它的内容就是文件里的字符串,并且它的最后有一个结束标志(这样就可以在系统里灵活使用了)。

C语言程序设计实验答案数组、指针与字符串

实验06 数组、指针与字符串(4学时) (第6章数组、指针与字符串) 一、实验目的 二、实验任务 6_1(习题6-25)编写并测试3×3矩阵转置函数,使用数组保存3×3矩阵。 6_2(习题6-26)使用动态内存分配生成动态数组来重新完成上题(n阶方阵),使用指针实现函数的功能。 6_3 编程实现两字符串的连接。要求使用字符数组保存字符串,不要使用系统函数。 6_4 使用string类声明字符串对象,重新实现上一小题。 6_5(习题6-27)声明一个Employee类。 其中包括姓名、街道地址、城市和邮编等属性,以及change_name()和display()等函数。display()显示姓名、街道地址、城市和邮编等属性,change_name()改变对象的姓名属性,实现并测试这个类。 6_6(习题6-27)声明包含5个元素的对象数组,每个元素都是Employee 类型的对象。 6_7 修改实验4中的people(人员)类。 具有的属性如下:姓名char name[11]、编号char number[7]、性别char sex[3]、生日birthday、身份证号char id[16]。其中“出生日期”声明为一个“日期”类内嵌子对象。 用成员函数实现对人员信息的录入和显示。 要求包括:构造函数和析构函数、拷贝构造函数、内联成员函数、聚集。 在测试程序中声明people类的对象数组,录入数据并显示。

三、实验步骤 1.(编程,习题6-25)编写矩阵转置函数,输入参数为3×3整型数组。 使用循环语句实现矩阵元素的行列对调,注意在循环语句中究竟需要对哪些元素进行操作,编写main()函数实现输入输出。程序名:lab6_1.cpp。 参考运行结果: ★程序及运行结果: //lab6_1.cpp #include using namespace std; void move(int matrix[][3]){ int temp; for(int i=0;i<3;i++) for(int j=0;j>mat[i][j]; } cout<<"\n输入的3×3矩阵为:"<

C语言字符数组总结

字符数组总结 字符数组不仅可以存储字符还可以存储字符串,而且存储字符串时必须包含…\0?,因为此字符是字符串的结束标志。因此,对字符数组的初始化、输入输出与一般数组又有不同。现总结如下: 数组的赋值(其中前两种赋值后不能以字符串进行处理) 1. 逐个元素赋值 char a[5]; a[0]=…C?; a[1]=…H?; a[2]=…I?; a[3]=…N?; a[4]=…A?; 2. 一般整体赋值 char a[5]={…C?, …H?, …I?,?N?,?A?}; char a[ ]={…C?, …H?, …I?, …N?, …A?} 3. 字符串整体赋值 char a[ ]={“abc”}; char a[ ]=“abc”; char a[4]={…a?,…b?,…c?,…\0?}; 字符串的输入(已知:char str[ 10 ]; int i;) 1. 逐个元素输入(必须输入9个) for(i=0;i<9;i++) scanf(“%c”,&str[i]); //此句也可以用str[i]=getchar();代替 str[9]=…\0?; 注意:?\0?只能直接赋值,不能从外部输入,外部输入的\0是\和0两个字符 2. 整个字符串输入(以空格,回车或TAB键结束) scanf(“%s”,str); 注意:此语句执行后自动会在str后添加一个?\0?,如:运行时输入:abc回车键,则str 中将有4个字符,依次为:?a?,?b?,?c?,?\0?,其中?\0?是自动添加上的。 3. 整个字符串输入(只以回车键结束) gets(str); 注意:此语句执行后自动会在str后添加一个?\0?,如:运行时输入:abc回车键,则str 中将有4个字符,依次为:?a?,?b?,?c?,?\0?,其中?\0?是自动添加上的。 字符串的输出(已知:char str[ 10 ]; int i;) 1. 逐个字符输出(注意此时for语句表示从第一个字符一直到?\0?) for(i=0;a[i]!=…\0?;i++) //此句中的a[i]!=…\0?;也可以用i

C语言数组编程题

实验4 数组 一.实验目的: 1.掌握一维数组的定义、赋值和输入输出的方法; 2.掌握字符数组定义、初始化、赋值的方法; 3.了解常见的字符串函数功能及其使用方法; 4.掌握二维数组的定义与引用。 二.实验内容: 1.编写程序,输入10个整数存入一维数组,统计输出其中的正数、负数和零的个数。 2.编写程序,输入10个整数存入一维数组,再按逆序重新存放后再输出。 3.编写程序,输入10个整数存入一维数组,对其进行升序排序后输出。 4.编写程序,求二维数组中元素的最大值和最小值。 5.编写程序,求一个4×4矩阵中所有元素之和。 6.编写程序:从键盘上输入一字符串,统计输出该字符串中的字母字符、数字字符、空格以及其他字符的个数。 7.编写程序:从键盘上输入一字符串,并判断是否形成回文(即正序和逆序一样,如“abcd dcba”)。 8. 产生一个由10个元素组成的一维数组并输出,数组元素由随机数(0-99)构成。 9. 产生一个由10个元素组成的一维数组,数组元素由随机数(0-99)构成。按照升序排列并输出。再输入一个数,按原来的规律将其插入并输出。 页脚内容1

10. 产生一个由10个元素组成的一维数组,数组元素由随机数(0-99)构成。按照升序排列并输出。再输入一个数,要求找出该数是数组中的第几个元素,如果不在数组中,则输出找不到。 11. 找出一个二维数组中的鞍点,即该位置上的元素在该行最大,在该列最小。可能没有鞍点。 12. 编程输出杨辉三角。(要求输出10行)(杨辉三角:每行端点与结尾的数为1.每个数等于它上方两数之和。每行数字左右对称,由1开始逐渐变大) 13. 输入一行字符,统计大写字母、小写字母、数字、空格以及其它字符个数。 14. 编写程序,将两个字符串连接起来,不用strcat。 15. 编写程序实现strcpy函数功能。 16. 编程实现strlen函数功能。 17. 编程求2-4+6-8…-100+102的值。 18. 假设某人有100,000现金。每经过一次路口需要进行一次交费。交费规则为当他现金大于50,000时每次需要交5%如果现金小于等于50,000时每次交5,000。请写一程序计算此人可以经过多少次这个路口。 19. 输入若干个正整数,以0结束,将其中大于平均值且个位为5的数排序后输出。(按由大到小的顺序排序) 20. 输入一个字符串,将其中ASCII码值为基数的字符排序后输出。(按由小到大的顺序) 21. 输入一个以回车结束的字符串(少于80个字符),滤去所有的非16进制字符后,组成一个新字符串(16进制形式),然后将其转换为10进制数后输出。 22. 读入一个正整数n(1<=n<=6),再读入n阶矩阵,计算该矩阵除副对角线、最后一行、最后一列 页脚内容2

C语言字符串的输入和输出

C语言字符串的输入和输出 字符串的输入和输出 %c人为加入\0进行输入输出 %s直接输入输出 *输入输出字符串时字符数组应有足够的存储空间,指针变量作为输入项时,指针必须已经指向确切的、足够大的存储空间 %s的使用 scanf("%s",地址值) 地址值:字符数组名、字符指针、字符数组元素的地址 例:char str[15]; scanf("%s",str); abc123 1.不读入空格和回车,从空格处结束 2.输入字符串长度超过字符数组元素个数,不报错 3.当输入项为字符指针时,指针必须已指向确定的有足够空间的连续 存储单元 4.当为数组元素地址时,从此元素地址开始存放 2.printf("%s",地址值) 输出时遇到第一个'\0'为止 3.gets和puts函数 开头必须stdio.h #include"stdio.h"

1.gets(地址值) 地址值:字符数组名、字符指针、字符数组元素的地址 4.当为数组元素地址时,从此元素地址开始存放 5.printf("%s",地址值) 输出时遇到第一个'\0'为止 6.gets和puts函数 开头必须stdio.h #include"stdio.h" 1.gets(地址值) 地址值:字符数组名、字符指针、字符数组元素的地址 7.例: char str[10]; gets(str); 包括空格符 8. 2.puts(字符串起始地址) 遇第一个'\0'结束,自动加入换行符 9.字符串数组:数组中每个元素都是一个存放字符串的数组 可以将一个二维数组看作是字符串数组 10.char ca[3][5]={"A","BB","CCC"}; A\0 B B\0 C C C\0 字符型指针数组 char*pa[3]={"a","bb","ccc"}; pa[0]pa[1]pa[2] 可以重新赋值gets(pa[2]);

c语言字符数组与字符串总结

字符数组与字符串 <1>定义 Char数组名[常量表达式] 数组中每一个元素的值为一个字符。 系统在内存为字符数组分配若干连续的存储单元,每个储存单元为一个字节。 <2>初始化 逐个元素初始化,如char c[8]={‘b’,’o’,’y’};(要记得加单引号) 用字符串初始化,如char c[11]={“I am a boy”};初始化后在末尾自动添加’0’ 如果初值个数<数组长度,则只将这些字符赋给数组中前面元素,其余元素自动定为空字符(即’0’) <3>输入输出 ①用格式”%c”逐个输入输出,如scanf(“%c”,&a[0]); ②用格式符”%s”整个字符串输入输出,如scanf(“%s”,a) 用”%s”格式输出字符数组时,遇’\0’结束输出,且输出字符中不含’\0’,用scanf及”%s”输入时,数组名前不能再加”&”符号。 字符串的末尾必须有’\0’字符,且字符串只能存放在字符数组中。 scanf中%s输入时遇空格或回车结束。 ③用函数gets实现输入 gets(字符数组),如gets(a) 调用函数时,回车键作为输入结束标志;然后将接收到的字符依

次赋给数组各个元素,并自动在字符串末尾加字符串结束标记’\0’ ④用字符串输出函数puts实现输出 puts(字符串/字符数组),如puts(a); 输出一个字符串,并在输出后自动换行。 <4>字符串处理函数 ①字符串拷贝函数 格式strcpy(字符数组1,字符串2) 将字符串2拷贝到字符数组1中去,要求字符数组1必须足够大,拷贝时’\0’一同拷贝,不能使用赋值语句为一个字符数组赋值。字符数组1应写成数组名的形式,比如char a[0]; strcpy(a,…) ②字符串连接函数 格式strcat(字符数组1,字符数组2) 将字符数组2连到字符数组1后面,要求字符数组1必须足够大,连接前,两串均以’\0’结束;连接后,串1的’0’取消,新串最后加’\0’。 ③计算字符串长度的函数 strlen(字符数组); 求出字符串或字符数组中实际字符个数,不包括’\0’,并且遇到’\0’结束。 ④字符串比较函数 格式strcmp(字符数组1,字符数组2)

第七章字符数组与指针练习题参考答案

第七章字符数组与字符串 【题7.29】下面是对s的初始化,其中不正确的是。 A)char s[5]={“abc”};B)char s[5]={‘a’,‘b’,‘c’}; C)char s[5]=“”;D)char s[5]=“abcdef”; 【题7.30】下面程序段的运行结果是。 char c[5]={‘a’,‘b’,‘\0’,‘c’,‘\0’}; printf(“%s”,c); A)‘a’‘b’ B)ab C)ab c 【题7.31】对两个数组a和b进行如下初始化 char a[]=“ABCDEF”; char b[]={‘A’, ‘B’,‘C’,‘D’,‘E’,‘F’}; 则以下叙述正确的是。 A)a与b数组完全相同B)a与b长度相同 C)a和b中都存放字符串D)a数组比b数组长度长 提示:‘\0’是字符串结束的标志 【题7.32】有两个字符数组a、b,则以下正确的输入格式是。 A)gets(a,b); B)scanf(“%s %s”,a,b); C)scanf(“%s %s”,&a,&b);D)gets(“a”),get(“b”); 【题7.33】有字符数组a[80]和b[80],则正确的输出形式是。 A)puts(a,b); B)printf(“%s %s”,a[],b[]); C)putchar(a,b); D)puts(a),puts(b); 【题7.34】下面程序段的运行结果是。 char a[7]=“abcdef”; char b[4]=“ABC”; strcpy(a,b); printf(“%c”,a[5]); A)空格B)\0 C)e D)f 提示:复制后a[0]=‘A’,a[1]=‘B’,a[2]=‘C’,a[3]=‘\0’, a[4]=‘e’,a[5]=‘f’, a[6]=‘\0’,

c语言编程技巧如何定义一个字符串的数组

C语言编程技巧:如何定义一个字符串的数组 实现目的 我们在用C语言编写程序时,经常会遇到使用字符串数组的情况,这种数组的特点是,数组中的每个元素都是一个字符串,但每个字符串的长度却不相同。如果你使用C++语言进行编程的话,实现起来相对比较简单,只需直接选择标准模板库的字符串string类,在代码中定义该类的一个数组即可实现。现在的问题是,在纯C语言中如何定义这样的一个字符串数组呢? 如对于下面的一个字符串数组: str = { “I love C.”, “I love C++.”, “I love JA V A.”, “I love Python.”, “I love LabVIEW.” }

下面给出C语言中的两种定义方法。 方法1:定义一个char类型的二维数组 这种方法是通过定义一个char类型的二维数组实现,通过二维数组的行索引可得到数组中的每个字符串,列的大小限定了每个字符串所能包含的最大字符个数,所以采用这种定义方式时,列的大小必须不能小于数组所有字符串的最大长度。如对于上面的数组,C语言的定义代码如下: 在取该数组的每个字符串时,直接对行索引即可。 方法2:定义一个指向char类型的指针数组 这种方法是通过定义一个指向char类型的指针数组实现,数组中的每个元素都是一个指针,通过该指针可得到数组中的每个字符串。如对于上面的数组,C语言的定义代码如下: 两种方法对比 上面的两种方法都可以实现我们的目的,但在内存的占用上两种方法不同。第1种方法定义了一个5行20列的二维数组,即每个字符串所占的字节长度都为20个,所以共需要占用100个字节,而第2种方法是定义的指针数组,每个指针指向的字符串占用的字节长度是其实际长度,所以其总的长度肯定小于100个字节。综合来讲,第1种方法相对于第2种方法,造成了存储空间的浪费情况。

关于C语言中的字符串数组输入输出控制符的若干问题

关于C语言中的字符串数组输入输出控制符的若干问题 示例一: #include void main() { int i; int a[6]; for(i=0;i<6;i++) { printf("please enter a number:\n" ); scanf("%d",&(a[i])); } printf("%d,%d,%d,%d,%d,%d",a[0],a[1],a[2],a[3],a[4],a[5]); //printf("%d",a); 这是错误做法,没有输出若干个实数的控制符,只能一个个输出。 } 实例二: #include void main() { int i; char a[6]; for(i=0;i<6;i++) { printf("please enter a number:\n" ); scanf("%s",&(a[i])); //只可从键盘输入一个字符,否则输出将每次输入多余的部分丢弃。 //不可写成:scanf("%c",&(a[i])); } printf("%c%c%c%c%c%c",a[0],a[1],a[2],a[3],a[4],a[5]); //不可用%s%s%s%s%s%s //也可以这样写:printf("%s",a); } 示例三: #include void main() { int i; char a[6]; for(i=0;i<6;i++) { printf("please enter a number:\n" ); scanf("%c",&(a[i])); getchar(); //如果用%c作为输入一个字符控制符用,后面必须加此句;

c语言数组习题

数组练习解答 1 定义一个名为a的单精度实型一维数组,长度为4,所有元素的初值均为0的数定义语句是___________ 【分析】按照一般数据定义语句的格式,可以直接写出方法一(参看答案);考虑到所有元素均赋初值时可以省略数组长度,可以写出方法二(参看答案);考虑到不省略数组长度,给部分元素赋初值时,所有未赋初值的元素均有空值(对数值型数组来说,初值为0),可以写出方法三(参看答案);考虑到选用静态型,不赋初值所有元素也自动赋予。空值(对数值型数组来说,初值为0),可以写出方法四(参看答案)。 【答案】方法一:float a[4]={0.0,0.0,0.0,0.0}; 方法二:float a[]={ 0.0,0.0,0.0,0.0}; 方法三:float a[4]= {0.0}; 方法四: static float [4]; 2 下列数组定义语句中,错误的是() ① char x[1]='a';②auto char x[1]={0}; ③ static char x[l];④ char x[l]; 【分析】显然答案①中给字符型数组赋初值的格式不对(不能直接赋予字符常量,必须用花括号括住),所以备选答案①是符合题意的答案。 【答案】① 3 用"冒泡排序法"对n个数据排序,需要进行n一1 步。其中第k步的任务是:自下而上,相邻两数比较,小者调上;该操作反复执行n-k次。现在假设有4个数据:4、l、3、2要排序,假定4为上、2为下,则利用"冒泡排序法"执行第2步后的结果是_________________。 【分析】开始排序前的排列执行第1步后的排列执行第2步后的排列 4 1 1 1 4 2 3 2 4 2 3 3 【答案】 l、2、4、3 4 用"选择排序法"对n个数据排序,需要进行n-1步。其中第k步的任务是:在第k个数据到第n个数据中寻找最小数,和第k个数据交换。现在假设有4个数据:4、1、3、2要排序,则利用"冒泡排序法"执行第2步后的结果是______________________。 【分析】开始排序前的排列为: 4 1 3 2 执行第1步后的排列为: 1 4 3 2 执行第2步后的排列为: 1 2 3 4 【答案】1、2、3、4 5 下列数组定义语句中,正确的是() ① int a[][]={1,2,3,4,5,6};② char a[2]「3]='a','b'; ③ int a[][3]= {1,2,3,4,5,6};④ static int a[][]={{1,2,3},{4,5,6}}; 【分析】C语言规定,二维数组定义时不允许省略第二维的长度,所以备选答案①④是错误的。C语言还规定,定义字符型数组时不允许直接使用"字符常量"的方式赋初值,所以备选答案②也是错误的。显然备选答案③符合题意。【答案】③ 6 定义一个名为"s"的字符型数组,并且赋初值为字符串"123"的错误语句是() ①char s[]={‘1','2','3','\0 '};②char s「」={"123"}; ③char s[]={"123\n"}; ④ char s[4]={'1','2','3'}; 【分析】备选答案①中省略了数组长度,所以每个元素都赋了初值,共计4个元素,初值依次为'l'、'2'、'3'、'\0',最后一个元素的值为字符串结束标记,所以数组S中存放的是字符串"123",该答案不符合题意(即正确的);备选答案③中直接赋予字符串作为初值所以数组s的长度为4,其中的初值是字符串"123",不符合题意(即正确的);备选答案③中也是给数组s赋予字符串的初值,但是字符串不是"123",而是"123\n",所以该答案符合题意(即错误的);显然答案④也不符合题意(即正确的)。下面来分析答案④为什么是正确的,该答案给出了数组长度为4,赋初值时仅给前3个元素赋予字符'1 '、 '2'、'3',第 4个元素没有赋初值,按照C语言的规定,也有初值,且初值为空值,对字符型数组来说,空值就是'\0',即字符率结束标记,所以数组S中存放的也是字符串" 123"。【答案】③

第8章 指针-3字符数组和字符指针 - 字符串的表示与存储

第8章指针——字符数组与字符指针:字符串的表示与存储

printf("How are you"); H o w a r e y o u \0

printf("How are you.\n "); printf("\"How are you.\"\n"); How are you. _ printf("How are you. Press \ a key and then press Enter:\n"); How are you. Press a key and then press Enter: _ "How are you." _ printf("How are you. Press " "a key and then press Enter:\n"); 问题:如果字符串太长,怎么表示?

?C语言没有提供专门的字符串数据类型 ?字符数组——每个元素都是字符类型的数组 H o w a r e y o u 0 H o w a r e y o u \0

?字符数组的定义 #define STR_LEN 80 char str[STR_LEN+1]; ?字符数组的初始化 用字符常量的初始化列表对数组初始化 char str[6] = {'C','h','i','n','a','\0'}; 用字符串常量直接对数组初始化 char str[6] = {"China"}; char str[6] = "China"; char str[ ] = "China"; char char str[10] = "China";

?字符指针就是指向字符串首地址的指针 ?定义一个字符指针,使其指向一个字符串常量 H e l l o C h i n a \0

字符数组,字符指针,sizeof,strlen总结

[cpp] 字符数组,字符指针,sizeof,strlen总结 作者:Hui Wang来源:博客园发布时间:2011-03-26 14:22 阅读:728 次原文链接[收藏]对于字符数组与字符指针: 1. 以字符串形式出现的,编译器都会为该字符串自动添加一个0作为结束符,如在代码中写"abc",那么编译器帮你存储的是"abc\0". 2. 字符串直接量作为字符指针的初始值 "hello"是一个字符串直接量,编译器将其作为const char*处理,与之相关联的内存空间位于内存的只读部分,即允许编译器重用指向等价字符串直接量的引用以优化内存使用, 即使程序中使用了字符串直接量500次,编译器在内存中也只是创建了一个实例。例如: char *ptr = “hello”; 等价于const char *ptr = “hello”; 字符串直接量"hello"关联的是只读内存,如果试图修改将出错,例如ptr[1] = …a?;是会引起错误的。 3. 字符串直接量作为基于栈的字符数组的初始值 由于基于栈的变量不可能引用其他地方存储的内存,编译器会负责将字符串直接量复制到基于栈的数组内存中。 例如: char stackArray[] = “hello”; 做如下修改: stackArray[1] = …a?;是真确的。 4. 字符数组与字符指针 字符数组的形式如下,会将字符直接量拷贝到栈上: char str[] = "abc"; // 实际的数据存储: a b c \0,也就是增加了一个终结符\0 char str[3] = {'a','b','c'}; // 实际的数据存储: a b c,并没有在最后添加终结符 char str[10] = {'a','b','c'}; // 实际的数据存储: a b c \0 \0 \0 \0 \0 \0 \0 字符指针的形式如下: char *str = “abc”;// 实际的数据存储: a b c \0,也就是增加了一个终结符\0 5. 类型的决定 1). 数组的类型是由该数组所存放元素的类型以及数组本身的大小决定的 如char s1[3]和char s2[4],s1的类型就是char[3],s2的类型就是char[4],也就是说尽管s1和s2都是字符数组,但两者的类型却是不同的。 2). 字符串常量的类型可以理解为相应字符常量数组的类型 如"abcdef"的类型就可以看成是const char[7],也就是说实际的数据存储为"abcdef\0"。 3). 函数参数列表中的以数组类型书写的形式参数,编译器把其解释为普通的指针类型

c语言中的字符数组与字符串

c语言中的字符数组与字符串 一、字符数组的定义 一维字符数组:用于存储和处理1个字符串,其定义格式与一维数值数组一样。char str[20]; 二维字符数组:用于同时存储和处理多个字符串,其定义格式与二维数值数组一样。 char country[10][20]; country[i]:第i个字符串 二.字符数组的初始化 字符数组的初始化. 1.可以通过为每个数组元素指定初值字符来实现。 char str[10]={ 'I',' ','a','m',' ',‘h’,'a','p','p','y'}; char str[ ]={"I am happy"}; 可以省略花括号,如下所示 char str[ ]="I am happy"; char country[10][20]={“china”,”japanese”,……}; 注意:上述这种字符数组的整体赋值只能在字符数组初始化时使用,不能用于字符数组的赋值,字符数组的赋值只能对其元素一一赋值,下面的赋值方法是错误的 char str[15]; str="I am happy"; strcpy(str, "I am happy"); 不是用单个字符作为初值,而是用一个字符串(注意:字符串的两端是用双引号“”而不是单引号‘’括起来的)作为初值。 ‘a’“a”区别 三、字符数组的引用 字符数组的逐个字符引用,与引用数值数组元素类似。 (1)字符数组的输入 除了可以通过初始化使字符数组各元素得到初值外,也可以使用getchar()或scanf()函数输入字符。 例如: char str[10]; …… for(i=0; i<10; i++) { scanf(\"%c\", &str); fflush(stdin); /*清除键盘输入缓冲区*/ }

字符串指针和字符数组,静态全局、静态局部、全局和局部变量区别,字符串常量和字符串变量,程序的内存分配

最近工作之余,发现了两个自己在C语言学习中的难点,一个是字符串指针和字符数组的区别,一个就是静态全局变量、静态局部变量、全局变量和局部变量的区别,在网上查了不少资料,收获良多,现在与大家分享,有错误的地方请大家指正! 以下程序用VC++6.0调试 先说说字符串指针和字符数组的区别 1.相同点: /* 用字符数组实现字符串操作*/ main( ) { char str[]="Welcome to study C !"; int i; printf("%s\n",str); for (i=0;i<=7;i++) printf("%c",str[i]); //用*(str+i)也行 printf("\n"); } /* 用字符指针实现字符串操作*/ main() { char *str="Welcome to study C !"; int i; printf("%s\n",str); for(i=0;i<=7;i++) printf("%c",*(str+i)); //用str[i]也行 printf("\n"); } 2.不同点: a)赋值方式不同,字符数组只能对各个元素分别赋值,而字符指针只需赋给字符串的 首地址就可以了。 如: char *str; str="Welcome to study C !"; 以下对字符数组的赋值是错误的: char str[80]; str[ ]="Welcome to study C !"; b)字符指针指向字符串,"hello"是一个字符串常量,与之相关联的内存空间位于内 存的只读部分,如: char ch[] = "china\n"; char *p; char *pp = "CHINA\n"; p = ch; *(p+2) = 'h';//就是可以的 *(pp+2) = 'h';//此处在编译时不会出错,在执行的时候会出错

C字符数组练习题及解答

第1题: 编写程序,比较两个字符串的大小,不允许使用strcmp函数。输入分2行,每一行均为字符串(不包含空格)。如果第一个字符串大于第二个字符串,则输出1;如果两个字符串大小相等,则输出0;如果第一个字符串小于第二个字符串,则输出-1。 样例输入: China China 样例输出:0 #include int main() {char a[100],b[100];int t=0,i;cin>>a;cin>>b; for(i=0;a[i]!=0||b[i]!=0;i++) {if(a[i]>b[i]){t=1;break;} if(a[i] #include int main() {char str1[100],i;int n; cin>>str1; n=strlen(str1); for(i=0;i #include int main() {int a[100],i,n,o,j;char str[100]; o=0; j=0; cin>>str; n=strlen(str); for(i=0;i

字符串,字符数组,字符指针

字符数组,字符指针,字符串 char a[]="hello world"; char* b="hello world"; string c="hello wolrd"; cout<

C语言中二维字符数组

C语言中二维字符数组 C语言中二维字符数组的定义和初始化 一般来说,我们可能会希望定义一个二维字符数组并且在定义的时候就用一些字符串来初始化它。比如说: 始化就最简单不过了。其中,MAX_LENGTH是所有字符串中最大的长度。当然不能忘记'\0'了。 而定义一个字符二维数组,C也提供了简洁的方式,如果我不想统计字符串的长度, 一定要指定的,像这样写 char **testcase = ... 是不行的,不过肯定不行了,因为int *pt=3 也不行,呵呵,这两个例子是一个道理啊。 我觉得肯定是人都喜欢第二种初始化方法了,而且它还有一个优点,起码对喜欢用指针的同志来说是一个大优点。就是可以将这样定义的指针赋给一个二维指针,比如char **pointer = testcase; 想形式1的定义方法肯定不能这样赋值了。 不过非常非常值得注意的是,上面定义的两个指针,一个一维,一个二维,他们必须在const关键字上一致,意思就是说如果定义testcase前面加了const关键字,定义pointer时也必须加上,否则就会报错: error C2440: 'initializing' : cannot convert from 'char *[30]' to 'const char ** 在写这篇日志的过程中,我突然想到一个问题,就似乎利用上面的方法二初始化二维字符串数组之中,字符串是如何分布的呢?因为字符串的长度是不相等的,完全由编译器来计算,那么它是会按照最长的字符串来定制字符数组的长度,还是让每一个字符串数组都按照自身的大小来占据内存,靠'\0'来识别结尾呢? 二维字符串数组的初始化-动态内存分配 昨天在用FBS200指纹采集芯片采集到一个二维数组数据后,利用串口传输上来的数据是以十六进制的数据格式表示的二维矩阵,比如“FF”、“BD”、“5C”等等这样

C语言字符数组初始化

1、字符数组的定义与初始化 字符数组的初始化,最容易理解的方式就是逐个字符赋给数组中各元素。 char str[10]={'I','','a','m','',‘h’,'a','p','p','y'}; 即把10个字符分别赋给str[0]到str[9]10个元素 如果花括号中提供的字符个数大于数组长度,则按语法错误处理;若小于数组长度,则只将这些字符数组中前面那些元素,其余的元素自动定为空字符(即'\0')。 2、字符数组与字符串 在c语言中,将字符串作为字符数组来处理。(c++中不是) 在实际应用中人们关心的是有效字符串的长度而不是字符数组的长度,例如,定义一个字符数组长度为100,而实际有效字符只有40个,为了测定字符串的实际长度,C语言规定了一个“字符串结束标志”,以字符'\0’代表。如果有一个字符串,其中第10个字符为'\0',则此字符串的有效字符为9个。也就是说,在遇到第一个字符'\0'时,表示字符串结束,由它前面的字符组成字符串。 系统对字符串常量也自动加一个'\0'作为结束符。例如"C Program”共有9个字符,但在内存中占10个字节,最后一个字节'\0'是系统自动加上的。(通过sizeof()函数可验证) 有了结束标志'\0'后,字符数组的长度就显得不那么重要了,在程序中往往依靠检测'\0'的位置来判定字符串是否结束,而不是根据数组的长度来决定字符串长度。当然,在定义字符数组时应估计实际字符串长度,保证数组长度始终大于字符串实际长度。(在实际字符串定义中,常常并不指定数组长度,如char str[])说明:'\n’代表ASCII码为0的字符,从ASCII码表中可以查到ASCII码为0的字符不是一个可以显示的字符,而是一个“空操作符”,即它什么也不干。用它来作为字符串结束标志不会产生附加的操作或增加有效字符,只起一个供辨别的标志。

最新C语言数组知识点总结

数组 定义:数组是有序的并且具有相同类型的数据的集合。 一维数组 1、一般形式:类型说明符数组名[常量表达式];例如:int a[10]; 元素为a[0]----a[9]. 2、常量表达式中不允许包含变量,可以包含常量或符号常量。 3、数组元素下标可以是任何整型常量、整型变量或任何整型表达式。 4、可以对数组元素赋值,数组元素也可以参与运算,与简单变量一样使用。 5、使用数值型数组时,不可以一次引用整个数组,只能逐个引用元素。 6、需要整体赋值时只可以在定义的同时整体赋值。如 int a[10]={0,1,2,3,4,5,6,7,8,9};正确。 int a[10]; a[10]={0,1,2,3,4,5,6,7,8,9};错误。 7、可以只给一部分元素赋值。例如: int a[10]={5,8,7,6};后面没有赋值的元素值默认为0。 8、对全部数组元素赋值时可以不指定数组长度,例如: int a[10]={0,1,2,3,4,5,6,7,8,9};可以写成int a[]={0,1,2,3,4,5,6,7,8,9}; 但是,既不赋初值,也不指定长度是错误的。例如:int a[];错误。 二维数组 1、一般形式:类型说明符数组名[常量表达式1][常量表达式2];例如: int a[3][4];可以看成是包含3个一维数组,每个一维数组里包含4个元素。一共3*4=12个元素。 所有元素为a[0][0],a[0][1],a[0][2],a[0][3] a[1][0],a[1][1],a[1][2],a[1][3] a[2][0],a[2][1],a[2][2],a[2][3] 2、与一维数组一样元素下标可以是是任何整型常量、整型变量或任何整型表达式。 3、需要整体赋值时只可以在定义的同时整体赋值。例如: int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};正确。 int a[3][4];a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};错误。 4、可以把所有数据写在一个花括号内。例如: int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};正确。 5、可以只对部分元素赋值。例如: int a[3][4]={{1},{5},{9}};其余未赋值的元素默认为0。 int a[3][4]={{1},{5,6}};可以看成是int a[3][4]={{1,0,0,0},{5,6,0,0},{0,0,0,0}}; 6、对全部数组元素赋值时可以省略第一维长度,第二维不可以省略。例如:

实验六 数组、指针与字符串 评讲

姓名:学号:班级: 2012计本 实验六数组、指针与字符串(4学时) ?实验目的 (1)学习使用数组数据对象 (2)学习字符串数据的组织和处理 (3)学习标准C++库的使用 (4)掌握指针的使用方法 (5)练习通过Debug 观察指针的内容及其所指的对象的内容 (6)练习通过动态内存分配实现动态数组,并体会指针在其中的作用(7)分别使用字符数组和标准C++库练习处理字符串的方法 ?实验任务 1)以例6-3为基础,观察对象数组的声明与引用过程,并与单对象的 引用过程的区别。 2)以例6-10为基础,观察用指针作为函数参数传递数据的方法,进一 步理解值传递与引用传递的思想 3)以例5-11为基础,完成例 5-25,比较二者的异同 4)编写并测试3*3矩阵转置函数,使用数组保存3*3矩阵。 5)使用动态内存分配生成动态数组来重新完成第(4)题,使用指针 实现函数功能 6)编程实现两字符串的连接。要求使用字符数组保存字符串,不要使 用系统函数。 7)使用string类声明字符串对象,重新实现第(6)。 8)声明一个Employee类,其中包括姓名、街道地址、城市和邮编等 属性,以及change_name()改变对象的姓名属性,实现并测试这个 类。

9)声明包含5个元素的对象数组,每个元素都是Employee类型对 象。 评讲部分 4)编写并测试3*3矩阵转置函数,使用数组保存3*3矩阵。 #include using namespace std; void move (int matrix[3][3]) { int i, j, k; for(i=0; i<3; i++) for (j=0; j> data[i][j]; } cout << "输入的矩阵的为:" << endl; for(i=0; i<3; i++) { for (j=0; j<3; j++) cout << data[i][j] << " "; cout << endl; } move(data); cout << "转置后的矩阵的为:" << endl; for(i=0; i<3; i++) { for (j=0; j<3; j++) cout << data[i][j] << " "; cout << endl; } }

相关主题
文本预览
相关文档 最新文档