字符串与指针

字符串与指针
字符串与指针

一、

C语言中,为什么字符串可以赋值给字符指针变量

char *p,a='5';

p=&a; //显然是正确的,

p="abcd"; //但为什么也可以这样赋值??

问:一直理解不了为什么可以将字串常量赋值给字符指针变量,请各位指点!

答:

双引号做了3件事:

1.申请了空间(在常量区),存放了字符串

2. 在字符串尾加上了'/0'

3.返回地址

你这里就是返回的地址赋值给了 p

二、

char *p = “hello”;

上边的表达式为什么可以,而把p换成数组,然后再赋值就不行了

解释:

字符串常量"hello"出现在一个表达式中时,"hello"表达式使用的值就是这些字符所存储的地址(在常量区),而不是这些字符本身。

所以,可以把字符串赋值给指向字符的指针p,而不能把字符串赋值给一个字符数组。

char a[10] = “hello”; //这样可以,这种情况是c语言初始化所支持的

如果写成char a[10]

然后a = “hello” 这样就错误了。

同样是a数组,char a[10] = “hello”;这种是数组的初始化,和a[0] = ‘h’ a[1] = ‘e’…是一个道理

但是换成char a [10]

然后a = “hello”就不行了“hello”赋值的值是一个地址,而a虽然也有地址,但是这与指针是不一样的,指针的值是地址,而数组的值虽然也是地址,但是却是一个常量,所以不能给常量赋值。

三、

标题:对字符数组,字符指针,字符串常量

原帖地址:https://www.360docs.net/doc/7b17729318.html,/25069424.html

1.以字符串形式出现的,编译器都会为该字符串自动添加一个0作为结束符,如在代码中写

"abc",那么编译器帮你存储的是"abc\0"

2."abc"是常量吗?答案是有时是,有时不是。

不是常量的情况:"abc"作为字符数组初始值的时候就不是,如

char str[] = "abc";

因为定义的是一个字符数组,所以就相当于定义了一些空间来存放"abc",而又因为

字符数组就是把字符一个一个地存放的,所以编译器把这个语句解析为

char str[3] = {'a','b','c'};

又根据上面的总结1,所以char str[] = "abc";的最终结果是

char str[4] = {'a','b','c','\0'};

做一下扩展,如果char str[] = "abc";是在函数内部写的话,那么这里的"abc\0"因为不是常量,所以应该被放在栈上。

是常量的情况:把"abc"赋给一个字符指针变量时,如

char* ptr = "abc";

因为定义的是一个普通字符指针,并没有定义空间来存放"abc",所以编译器得帮我们

找地方来放"abc",显然,把这里的"abc"当成常量并把它放到程序的常量区是编译器

最合适的选择。所以尽管ptr的类型不是const char*,并且ptr[0] = 'x';也能编译

通过,但是执行ptr[0] = 'x';就会发生运行时异常,因为这个语句试图去修改程序

常量区中的东西。

记得哪本书中曾经说过char* ptr = "abc";这种写法原来在c++标准中是不允许的,

但是因为这种写法在c中实在是太多了,为了兼容c,不允许也得允许。虽然允许,

但是建议的写法应该是const char* ptr = "abc";这样如果后面写ptr[0] = 'x'的

话编译器就不会让它编译通过,也就避免了上面说的运行时异常。

又扩展一下,如果char* ptr = "abc";写在函数体内,那么虽然这里的"abc\0"被

放在常量区中,但是ptr本身只是一个普通的指针变量,所以ptr是被放在栈上的,

只不过是它所指向的东西被放在常量区罢了。

3.数组的类型是由该数组所存放的东西的类型以及数组本身的大小决定的。

如char s1[3]和char s2[4],s1的类型就是char[3],s2的类型就是char[4],也就是说尽管s1和s2都是字符数组,但两者的类型却是不同的。

4.字符串常量的类型可以理解为相应字符常量数组的类型,

如"abcdef"的类型就可以看成是const char[7]

5.sizeof是用来求类型的字节数的。如int a;那么无论sizeof(int)或者是sizeof(a)都

是等于4,因为sizeof(a)其实就是sizeof(type of a)

6.对于函数参数列表中的以数组类型书写的形式参数,编译器把其解释为普通的指针类型,如对于void func(char sa[100],int ia[20],char *p)

则sa的类型为char*,ia的类型为int*,p的类型为char*

7.根据上面的总结,来实战一下:

对于char str[] = "abcdef";就有sizeof(str) == 7,因为str的类型是char[7],

也有sizeof("abcdef") == 7,因为"abcdef"的类型是const char[7]。

对于char *ptr = "abcdef";就有sizeof(ptr) == 4,因为ptr的类型是char*。对于char str2[10] = "abcdef";就有sizeof(str2) == 10,因为str2的类型是char[10]。

对于void func(char sa[100],int ia[20],char *p);

就有sizeof(sa) == sizeof(ia) == sizeof(p) == 4,

因为sa的类型是char*, ia的类型是int*,p的类型是char*。

四、

C语言中字符数组和字符串指针分析,该贴原址:

https://www.360docs.net/doc/7b17729318.html,/gigikouyi/archive/2006/08/01/464737.html

这几天搞Unix上的C程序,里面用到了很多字符数组和字符串指针,我记得在学完C语言后相当一段时间里,对指针这个东西还是模模糊糊,后来工作也没怎么用到过C,虽然网上这类的文章也有很多,还是决定自己在这做个小总结,也算加深下自己的印象,写了下面的测试程序:

#include

int main(int argc, char *argv[])

{

char day[15] = "abcdefghijklmn";

char* strTmp = "opqrstuvwxyz";

printf("&day is %x\n",&day);

printf("&day[0] is %x\n",&day[0]);

printf("day is %x\n",day);

printf("\n&strTmp is %x\n",&strTmp);

printf("&strTmp[0] is %x\n",&strTmp[0]);

printf("strTmp is %x\n",strTmp);

getchar();

return 0;

}

运行后屏幕上得到如下结果:

其实看到结果估计很多东西就好明白了,

先看看前三个输出也就是关于变量day的,在 char day[15] = "abcdefghijklmn"; 这个语句执行的时候,系统就分配了一段长15的内存,并把这段内存起名为day,里面的值为"abcdefghijklmn",如下图所示:

再看程序,第一个输出,&day,&号是地址运算符,也就是day这个变量的内存地址,很明显,在最前面,也就是a字符所在字节的地址;

对于第二个输出也就好理解了,&day[0],就是day数组中第一个变量(也就是a)的地址,因此他们两个是一样的;

第三个输出是day,对于数组变量,可以使用变量名来索引变量中的内容,其实这里的day可以理解成数组变量退化的指针,并且指向数组的开头,既然把它理解成指针,那么它的值肯定是地址了,所以他的值和上面两个也一样。

再看看后面三个输出,关于字符串指针strTmp,在执行char* strTmp = "opqrstuvwxyz";后,内存的图示如下:

如图所示,内存分配了两段内存,一个名为strTmp,类型是一个字符指针,另外一段是一个字符串常量,且strTmp里面存放着字符常量的首地址,注意这里无法通过strTmp修改这段字符串,因为是常量;于是程序中的后面三个输出就好理解了;

&strTmp:strTmp这个字符指针的地址

&strTmp[0]:strTmp所指字符常量第一个字符的地址

strTmp:strTmp这个字符指针的值,即字符常量的首地址

因此,最后两个的值是一样的。

指针可以这样理解,指针这种类型,和int,char,double等等是一样的,只是它用来保存地址值的,而int变量保存整数,char变量保存字符,仅此而已,就char型指针或者int指针,本质是一样的,都是存放的地址,只不过那个地址所里面的变量类型不同而已,还有一种void型指针,就是可以放任何类型变量的地址。

五、

个人代码以及注释,纯属个人理解,定有不妥之处,望批评指正:

#include

int main(int argc, char *argv[])

{

char* strTmp = "abcd";

printf("strTmp is %s\n",strTmp);//将字符串常量"abcd"的地址所隐含的内容转换成“string类型”

printf("strTmp is %d\n",strTmp);//将字符串常量"abcd"的地址转换成int 类型,这里不同的机子不同的时间的运行结果可能会不一样,因为地址可能会发生变化

printf("strTmp is %c\n",strTmp);//将字符串常量"abcd"的地址转换成字符型,这里不同的机子不同的时间的运行结果可能会不一样,因为地址可能会发生变化

printf("*strTmp is %c\n",*strTmp);//将字符串常量"abcd"的地址所隐含的内容转换成字符型,由下面注释的这句会抛出异常可知,这里并无截取字符串,*strTmp长度本身就是1

//printf("*strTmp is %s\n",*strTmp);//不能将字符转换成字符串型

getchar();

return 0;

}

六、

后来又有看到下面这样的说法可供读者参考:

1. C语言中没有字符串类型,只有用字符数组来表示。这和c++中string是有区别的,C++中string是可以直接赋值如string s;s="Hello world";但是C语言中的字符数组却不能这样。所以,这里的strTmp可以理解为字符数组的首地址,也可以用它代表整个字符数组,所以能输出所有字符数组中的内容。

2.字符串就是字符数组或者是指针。内存实现都一样的。数组名字就是一个指针。

char ch[100] ;

char *p;

p =ch;

3.定义的字符串方式举例:

字符串定义其实很简单在c/c++语言中定义一个字符串可以使用如下的语法:

char *s1=“string1”;//定义字符串常量,指针形式

char s2[]=“string2”;//定义字符串常量,数组形式

char *s3=new char[10];//定义字符串变量并分配内存指针形式

strcpy(s3,"string3");//为s3赋值

char s4[10];//定义字符串变量,数组形式

strcpy(s4,"string4");//为s4赋值

以上四种方法都能定义一个字符串,同时通过字符串在内存中的分布可以清楚地知道是什么情况

4. C语言中字符串赋值方法strcpy(char*d,char*s)其中s代表是源字符串,d 代表目标字符串,也就是你要赋值的字符串。

5.c语言中的字符串跟java或c++中的字符串不同。如char *p;其中p是一个指针,p中存储一个内存缓冲区的首地址。所谓的内存缓冲区就是一段连续的内存地址,里面存放了一系列的字符。那系统又是如何判断在哪里结束呢。那就是根据符号‘\0’。这个字符占一个字节,8位,每位的值都是0。

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语言字符串指针问题

C语言字符串指针问题 在C语言中,可以用两种方法访问一个字符串。 用字符数组存放一个字符串,然后输出该字符串。 1.main(){ 2.char string[]=”I love China!”; 3.printf("%s\n",string); 4.} 说明:和前面介绍的数组属性一样,string是数组名,它代表字符数组的首地址。 用字符串指针指向一个字符串。 1.main(){ 2.char *string=”I love China!”;

3.printf("%s\n",string); 4.} 字符串指针变量的定义说明与指向字符变量的指针变量说明是相同的。只能按对指针变量的赋值不同来区别。对指向字符变量的指针变量应赋予该字符变量的地址。如: char c,*p=&c; 表示p是一个指向字符变量c的指针变量。而: char *s="C Language"; 则表示s是一个指向字符串的指针变量。把字符串的首地址赋予s。 上例中,首先定义string是一个字符指针变量,然后把字符串的首地址赋予string(应写出整个字符串,以便编译系统把该串装入连续的一块内存单元),并把首地址送入string。程序中的:char *ps="C Language"; 等效于: char *ps; ps="C Language"; 输出字符串中n个字符后的所有字符。 1.main(){ 2.char *ps="this is a book";

3.int n=10; 4.ps=ps+n; 5.printf("%s\n",ps); 6.} 运行结果为: book 在程序中对ps初始化时,即把字符串首地址赋予ps,当ps= ps+10之后,ps指向字符“b”,因此输出为"book"。 在输入的字符串中查找有无‘k’字符。 1.main(){ 2.char st[20],*ps; 3.int i; 4.printf("input a string:\n"); 5.ps=st; 6.scanf("%s",ps); 7.for(i=0;ps[i]!='\0';i++) 8.if(ps[i]=='k'){ 9.printf("there is a 'k' in the string\n"); 10.break; 11.} 12.if(ps[i]=='\0') printf("There is no 'k' in the string\n");

指针的定义与初始化

int a; float b; a=3; b=5; 3AB0 a 3AB8 b 35

?变量与地址 程序中: int i; float k; 内存中每个字节有一个编号-----地址…... …... 2000200120022005 内存 2003 i k 编译或函数调用时为其分配内存单元 变量是对程序中数据存储空间的抽象

…... …... 2000 20042006 2005整型变量i 10 变量i _pointer 2001 20022003?指针:一个变量的地址 ?指针变量:专门存放变量地址的变量叫~ 2000 指针 指针变量 变量的内容 变量的地址 指针变量变量变量地址(指针) 变量值 指向 地址存入指针变量

指针变量与其所指向的变量之间的关系 ? 一般形式:[存储类型] 数据类型*指针名; 变量i*i_pointer 3 i 2000 i_pointer *i_pointer &i i_pointer i=3;*i_pointer=3 合法标识符指针变量本身的存储类型 指针的目标变量的数据类型 表示定义指针变量 不是‘*’运算符 例int*p1,*p2; float *q ; static char *name; 注意: 1、int *p1, *p2;与int *p1, p2; 2、指针变量名是p1,p2 ,不是*p1,*p2 3、指针变量只能指向定义时所规定类型的变量 4、指针变量定义后,变量值不确定,应用前必须先赋值 指针的定义

?指针是一种变量,在定义的同时可以赋给它初始值,称为指针的初始化。 ?形式如下: 类型标识符*指针名=初始地址值; 例如, int m,n[8];char c; int *pm = &m;int *pn = n;char *pc = &c; 变量地址作初值时, 该变量在此之前已说明过,且类型应一致。 可用已赋初值的指针 去初始化其他指针变量.

指向指针的指针——彻底搞定C指针

彻底搞定C指针---指向指针的指针 彻底搞定C指针---指向指针的指针一.回顾指针概念: 今天我们又要学习一个叫做指向另一指针地址的指针。让我们先回顾一下指针的概念吧! 当我们程序如下申明变量: short int i; char a; short int * pi; 程序会在内存某地址空间上为各变量开辟空间,如下图所示。 内存地址→6 7 8 9 10 11 12 13 14 15 ------------------------------------------------------------------------------------- … | | | | | | | | | | ------------------------------------------------------------------------------------- |short int i |char a| |short int * pi| 图中所示中可看出: i 变量在内存地址5的位置,占两个字节。 a变量在内存地址7的位置,占一个字节。 pi变量在内存地址9的位置,占两个字节。(注:pi 是指针,我这里指针的宽度只有两个字节,32位系统是四个字节) 接下来如下赋值: i=50; pi=&i; 经过上在两句的赋值,变量的内存映象如下: 内存地址→6 7 8 9 10 11 12 13 14 15 -------------------------------------------------------------------------------------- … | 50 | | | 6 | | | | -------------------------------------------------------------------------------------- |short int i |char a| |short int * pi| 看到没有:短整型指针变量pi的值为6,它就是I变量的内存起始地址。所以,这时当我们对*pi进行读写操作时,其实就是对i变量的读写操作。如:*pi=5; //就是等价于I=5; 你可以回看本系列的第二篇,那里有更加详细的解说。 二.指针的地址与指向另一指针地址的指针 在上一节中,我们看到,指针变量本身与其它变量一样也是在某个内存地址中的,如pi的内存起始地址是10。同样的,我们也可能让某个指针指向这个

如何透彻理解C语言中指针的概念

如何透彻理解C语言中指针的概念 强大的指针功能是C语言区别于众多高级语言的一个重要特征。C语言指针的功能强大,使用灵活多变,可以有效地表示复杂的数据结构、动态分配内存、高效地使用数组和字符串、使得调用函数时得到多个返回值。而它的应用远不限于此。初学者对于指针的概念总是感到无所适从,有时觉得“自己懂了,为什么编译器就是不懂呢”,常有茫然和无助的感觉。 学好指针的关键在于深入了解内存地址的空间可以理解为一个一维线性空间,内存的编址和寻址方法,以及指针在使用上的一些规定。事实上,指针就是方便我们对内存地址直接进行操作的,是为程序员服务的,我们只要抓住指针想要帮助我们解决什么问题这个核心,就可以轻松地理解它的工作原理。 什么是指针,指针有什么作用 指针就是指向一个特定内存地址的一个变量。简化了的内存空间模型是按照从0到某一个数(比如1048575=1M-1)的一维线性空间,其中的每一个数对应一个存储单元,即1个字节。指针有两个属性:指向性和偏移性。指向性指的是指针一定要有一个确定的指向,偏移性则是体现指针重要应用的方面,即指针可以按程序员的要求向前或向后偏移。 指针的应用往往与数组联系在一起,为了方便说明问题,不妨从数组开始解释指针的偏移。数组就是许多的变量,它的一个重要特征就是在内存空间中连续地存放,而且是按下标顺序存放。比如我们定义一个有100个变量的一维整型数组,它一定从内存的某一个存储单元开始按数组下标顺序存放,连续占用100*4=400字节。当我们定义一个数组时,系统就会自动为它分配一个指针,这个指针指向数组的首地址。(在本文剩余部分的论述中,不加区分地使用“指向数组的首地址”与“指向数组的第一个元素”这两种说法,事实上这两种说法也是一致的。) 为了让系统了解每一次指针偏移的单位,也为了方便程序员进行指针偏移(让程序员记住一个整形变量占用4字节,一个字符型变量占用1字节……等等是很麻烦的),不用每次去计算要偏移多少个字节,C语言引入了指针的基类型的概念。基类型的作用就是让系统了解某个指针每次偏移的字节数。比如,对于一个字符型指针,它每次偏移(比如ptr=ptr+1)所起到的作用就是让指针偏移1字节;而对于一个整型指针,它每次偏移就应该是4字节。这样操作数组时就带来了方便。比如对于一个指向某个整型数组起始存储单元(称为首地址)的指针ptr,ptr=ptr+1就表示将该指针指向这个数组的下一个元素的存储单元,即向后移动4字节,而不仅仅是移动一个存储单元(即移动1字节)。 &()、*()、和[ ]运算符的意义 在本文中,将&()、*()和[ ]都看成是运算符。这样可以方便理解这三个概念。简单地说,&()将某个标识符(比如变量)转化为其在内存空间中的地址,而*()是产生一个对应于某个地址的标识符,[ ]就更复杂一点,ptr[i]表示

指针的初始化和定义

每个指针都有一个与之关联的数据类型,该数据类型决定了指针所有指向的对象的类型。例如,一个int 型指针只能指向int 型对象。 1.指针变量的定义 C++语言使用* 号把一个标识符声明为指针: vector *pvec; int *p1, *p2; string *pstring; 提示:理解指针声明语句时,请从右向左阅读。 2.另一种声明指针的风格 在定义指针变量时,可用空格符号* 与气候的标识符分别开来,如下: string* ps; 也就是说,该语句把ps定义为一个指向string 类型对象的指针。 这种指针声明风格容易引起这样的误解:把string * 理解为一种数据类型,认为在同意声明语句中定义的其他变量也指向string 类型对象的指针。 如果使用下面的语句: string* p1, p2;

实际上只把ps1 定义为指针,而ps2并非指针,只是一个普通的string 对象而已。如果需要在一个声明语句中定义了两个指针,必须在每一个变量标识符前再加符号* 声明: string* ps1,*ps2; 3.指针的可能取值 一个有效的指针必然是以下三种状态之一:1.保存一个特定对象的地址;2.指向某个对象后面的另一对象;3.是0值。若指针保存0值,表明它不指向任何对象。未初始化的指针是无效的,直到给该指针赋值后,才可以使用它。下面的定义是合法的: int ival = 1024; int *pi = 0; int *pi2 = &ival; int *pi3; pi = pi2; pi2 = 0; 4.避免使用未初始化的指针 提示:很多运行时错误都源于使用了未初始化的指针。 就像使用其他没有初始化的变量一样,使用未初始化的指针时的行为C++标准中并没有定义,它几乎总会导致运行时崩溃。然而,导致崩溃的这一原因很难发现。

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

第七章字符数组与字符串 【题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语言指针习题__附答案[1]

一、选择题 1.变量的指针,其含义是指该变量的_________. a)值b)地址 c)名d)一个标志 2.若有语句int *point,a=4;和point=&a;下面均代表地址的一组选项是_____. a)a,point,*&a b)&*a,&a,*point c)*&point,*point,&a d)&a,&*point ,point 3.若有说明;int *p,m=5,n;以下正确的程序段的是________. a)p=&n; b)p=&n; scanf("%d",&p); scanf("%d",*p); c)scanf("%d",&n); d)p=&n; *p=n; *p=m; 4. 以下程序中调用scanf函数给变量a输入数值的方法是错误的,其错误原因是________. main() { int *p,*q,a,b; p=&a; printf(“input a:”); scanf(“%d”,*p); …… } a)*p表示的是指针变量p的地址 b)*p表示的是变量a的值,而不是变量a的地址 c)*p表示的是指针变量p的值 d)*p只能用来说明p是一个指针变量 5. 已有变量定义和函数调用语句:int a=25; print_value(&a); 下面函数的正确输出结果是________. void print_value(int *x) { printf(“%d\n”,++*x);} a)23 b)24 c)25 d)26 6.若有说明:long *p,a;则不能通过scanf语句正确给输入项读入数据的程序段是 A) *p=&a;scanf("%ld",p);

指针经典练习题及答案

二、程序题 1、计算字符串中子串出现的次数。要求:用一个子函数subString()实现, 参数为指向字符串和要查找的子串的指针,返回次数。 2、加密程序:由键盘输入明文,通过加密程序转换成密文并输出到屏幕上。 算法:明文中的字母转换成其后的第4个字母,例如,A变成E(a变成e), Z变成D,非字母字符不变;同时将密文每两个字符之间插入一个空格。 例如,China转换成密文为G l m r e。 要求:在函数change中完成字母转换,在函数insert中完成增加空格, 用指针传递参数。 3、字符替换。要求用函数replace将用户输入的字符串中的字符t(T)都替换为e(E), 并返回替换字符的个数。 4、编写一个程序,输入星期,输出该星期的英文名。用指针数组处理。 5、有5个字符串,首先将它们按照字符串中的字符个数由小到大排列, 再分别取出每个字符串的第三个字母合并成一个新的字符串输出 (若少于三个字符的输出空格)。要求:利用字符串指针和指针数组实现。 6、定义一个动态数组,长度为变量n,用随机数给数组各元素赋值, 然后对数组各单元排序,定义swap函数交换数据单元,要求参数使用指针传递。7、实现模拟彩票的程序设计:随机产生6个数字,与用户输入的数字进行比较, 输它们相同的数字个数(使用动态内存分配)。 /*1、计算字符串中子串出现的次数。要求:用一个子函数subString()实现, 参数为指向字符串和要查找的子串的指针,返回次数。*/ #include int subString(char *a, char *b) { int i = 0; int j = 0; int m = 0; char *p = b; while(*a) { while(*a) { if(*a == *b) { break; } a++; } while(*b) { if(*a != *b)

C、C++字符串指针(指向字符串的指针)

C、C++字符串指针(指向字符串的指针) C语言中没有特定的字符串类型,我们通常是将字符串放在一个字符数组中,这里我们来演示一下: #include #include #include int main(){ char str[] = "hello world !"; int len = strlen(str), i; //直接输出字符串 printf("%s\n", str); //每次输出一个字符 for(i=0; i #include #include

int main() { char str[] = "hello world !"; char *pstr = str; int len = strlen(str), i; //使用*(pstr+i) for (i = 0; i

字符数组,字符指针,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). 函数参数列表中的以数组类型书写的形式参数,编译器把其解释为普通的指针类型

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

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

指向字符串的指针数组

在初学习C语言时,对于指针是最容易让人迷糊的,尤其对于指针数组,而且是指向字符串的指针数组,恐怕就更难理解了。下面本人给出一个例子,详细讲解指向字符串的指针数组的使用情况。希望给予学习C的朋友一点帮助。 下述程序执行后,输出结果是什么? #include char *p[2][3]={ "abc","defgh","ijkl","mnopqr","stuvw","xyz"}; main(){ printf("%c\n",***(p+1)); printf("%c\n",**p[0]); printf("%c\n",(*(*(p+1)+1))[4]); printf("%c\n",*(p[1][2]+2)); printf("%s\n",**(p+1)); } 答案是: m a w z mnopqr 答案解析: 这里相当于定义了2行3列共6个元素的数组,数组的每一个元素都是指向字符的指针变量。 其中p[0][0]指向串"abc",p[0][1]指向串"defgh",p[0][2] 指向串"ijkl",p[1][0]指向串"mnopqr",p[1][1]指向串"stuvw",p[1][2] 指向串"xyz"。 1、printf("%c\n",***(p+1)); 这里的***(p+1)相当于*(*(*(p+1)+0)+0),而*(*(p+1)+0)+0)的另一种容易懂的形式是p[1][0],在多维数组中这两种写法等价。如上面所写的p[1][0]是指向串"mnopqr",即保存的是串"mnopqr"的首地址,也即字母m的地址。因此***(p+1)是字母m 2、printf("%c\n",**p[0]); 这里的**p[0]等价于*(*(*(p+0)+0)+0),也即*(p[0][0]),而p[0][0])指向串"abc",所以*(p[0][0])是字符a 3、printf("%c\n",(*(*(p+1)+1))[4]); (*(*(p+1)+1))[4]等价于*((p[1][1])+4),而(p[1][1])指向串"stuvw",所以*((p[1][1])+4)是在串首向后移动4个单位的字符,也即w 4、printf("%c\n",*(p[1][2]+2)); 因为p[1][2]指向串"xyz",而p[1][2]+2 就是串首向后移动2个字节(一个字节保存一个字符),也就是指向字符z,所以*(p[1][2]+2)是字符z

字符串的指针和函数的指针.

实验10 字符串的指针和函数的指针 一、实验学时:2课时 二、实验目标 1.学会使用字符串的指针和指向字符串的指针变量; 2.学会使用指向函数的指针变量; 3.了解指向指针的指针的概念及其使用方法。 三、实验要求: 1.在实验课前,每位同学必须将预习有关数组与函数的内容,了解他们的关 系; 2.在上实验课之前,每一个同学必须将实验的题目、程序编写完毕,做好充 分的准备。 3.所有实验环节均由每位同学独立完成,严禁抄袭他人实验结果,若发现有 结果雷同者,按实验课考核办法处理。 四、实验步骤和内容 1. 分析下列程序的运行结果,并上机验证。 1) int ff( char *x ) { char *p=x, *q; int i, k=1; q = p+strlen(x)-1; for ( i=1; i<=strlen(x)/2; i++) if (*p==*q) { p++; q--; } else { k=0; break; } return k; } 若从键盘输入asdfghgfdsa则输出结果为:______________________ 若从键盘输入aweftfew 则输出结果为:______________________ void main() { char a[80]; gets(a); if ( ff (a)==1 ) printf( "*****\n"); else printf("%%%\n"); }

用户自定义函数的功能是:___________ 2. 以下是求三个数中的最大数的程序,试完成程序。 void cut( int *p, int *q) { int t; t=*p;___________; *q=t; } void main() { int a, b, c; scanf( "%d%d%d", &a, &b, &c ); if ( a

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

最近工作之余,发现了两个自己在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';//此处在编译时不会出错,在执行的时候会出错

指针的定义,初步应用

1,变量a本质上代表一个储存单元。Cpu通过该储存单元的地址访问储存单元中的数据。 变量a本来就代表两个意思:存储单元的地址和存储单元中的数据。为了消除这种二义性,C语言规定a表示存储单元中的数据,&a表示存储单元的地址。A存储单元中的数据可以是一个普通数值,也可以是另一个存储单元的地址。比如a=&b就是将b的存储单元的地址存入a存储单元中。C语言规定*a代表a的存储单元的地址对应的存储单元的数据,也就是访问了*a就是访问b,于是*a提供了通过a访问b中的数据的手段。2,利用变量名,直接对变量进行操作叫直接访问, 3,将a+b的和送到被这个指针变量所指变量的那个空间中。我们已经知道了这个变量指向变量c,所以变量c的值就是a和b之和。 通过另一个变量的值来访问该变量的值称为间接访问。 变量的地址称为变量的指针。 C语言规定所有变量都要先说明再使用。 4,int* p int代表指针变量所指的类型。该指针变量只能指向整形变量。只能用表示地址的数据为指针初始化或赋值。(例如数组名,&变量名)。数组名代表了数组元素的起始地址。 还有一点就是相同类型的指针变量可以相互赋值。表示两个指针指向了同一个变量。

*px就是声明的时候指示px是一个指针。在定义处和下边*px代表的意思不一样。Px=3和*px=3. 不加星号就是把变量对应的地址改变了,加星号就是改变地址所对应的存储空间的内容了,也就是改变了指针指向变量的值。 4,一个指针只要被定义了,被赋值了,指针就可以用来引用被他所指的变量。 指针数组int *p3, int(*p)[3] 5,注意指针的概念辨析。 指针的值,就是指针所指的那块内存区域。 普通变量做函数的参数无法通过调用函数来完成数据的交换。 在被调用函数中形参也是指针。 这个图中指针的指向没有变化,但是指向的内容(值)变了。虽然调用完后地址被释放,但是内容没有被释放(找了个替死鬼。。。)。也就是说把实参的值给换了。 在非定义的部分出现*p。对指针做间接访问就意味着获得了指针所指变量的值。 实参指针,形参指针获得了同样的变量的地址,也就指向了相同的变量。 一旦指针被赋值了,我们对这个变量的引用被称为对变量的直接访问。

指针的概念

指针的概念 指针是C++所提供的一种颇具特色的数据类型,允许获取和直接操纵数据地址,实现动态存储分配。掌握指针的应用,可以使程序简洁、紧凑、高效,并且能更有效地使用宝贵的内存空间。指针是C和C++的精华所在,也是C和C++的一个十分重要的概念。 主要内容:指针的概念; 指针数据对象的定义; 指针运算; 指针数据对象的引用; 利用指针实现动态存储分配(动态数组)。 重点:指针的概念、动态存储分配。 一、指针的概念 1.什么叫指针 一个数据对象的内存地址称为该数据对象的指针。指针可以表示简单变量、数组、数组元素、结构体甚至函数。也即指针具有不同的类型,可以指向不同的数据存储体。例如: int *point1,a,b; double *point2[20]; …… point1=&a; point1 整型变量a point2[0] 双精度形数组 Point1 = &b; Point1 整型变量b 图6.1 指针示意 注意:指针中的内容是可以动态改变的,例如point1既可以指向变量a也可以指向变量b。2.指针的作用 1)能实现复杂的数据结构,例如数组、链表、队列和堆栈等;

2)能方便地表示和处理字符串; 3)能方便地实现动态存储分配; 如果一个程序或者一个函数出现使用需要大存储量的数据对象,采用动态存储分配可以提高内存的使用率,也即这些数据一般用预先定义的指针变量来表示,当实际使用时才临时申请实际的存储空间,使用完毕立即释放。指针变量所占的内存空间与所表示的数据对象的存储空间相比实在是微乎其微,因为它只是用来存放对应空间的首地址。 4)在函数之间进行数据的双向传递。 将形参定义成指针类型,对应的实参必须是某个数据对象的首地址,也即采用传地址的方式,这样就可以实现数据的双向传递。 3.指针类型 指针类型属于标准类型,其取值是所表示的数据对象的内存地址,所以其值域是内存地址集。指针类型用来定义各种类型的指针变量,其语法如下: <类型标识符> * 例如 int *表示整型指针类型,char *表示字符指针类型,等等。 二、定义指针变量 同其他变量一样,指针变量也必须“先定义后使用”,可以在函数外部定义全局的指针变量也可以在函数内部定义局部的指针变量。 1.语法 <类型标识符> *<标识符1>,*<标识符2>,……,*< 标识符n>; ;类型标识符:用来指明指针的类型,可以是基本类型,例如int,char,double等等,也可以是结构类型,例如结构体,文件等等。υ ;*:表示指针。υ ;标识符:指针数据对象的名字,可以是基本变量名、数组名、结构体变量名、函数名等。υ2.实例 (1)int *x, *y,z; 上面的语句定义了三个变量,其中z是整型变量,用来存放整数,x,y是整型指针变量,用来存放整型数据对象的内存地址,或者说用来表示整型数据对象。 z=5; x=&z; z中存放整数5,也即z的值是5;x中存放的是z的地址,我们可以用*x来表示z。x和z的关

实验4(数组、指针、字符串)

实验二C++程序设计基础 一、实验目的 (1)、学习并掌握指针的性质 (2)、掌握指针参数的运用,进一步掌握引用的使用方法 (3)、学习函数指针的应用和带参数的main函数 (4)、学习掌握指针与引用、指针与数组、指针与字符串的用法 二、实验内容及步骤 1、选择题 (1)已知一函数的形参说明为int arr[5][6],在下列说明中,与此等效的形参说明为__________。 A. int arr[][] B. int [5][] C. int *a[6] D. int (* a)[6] (2)已知函数f的原型是:int f(char a,char * b=NULL,double c=0.0); 则下列调用中,不能正确地调用f函数的是__________ 。 A. f(99) B. f(‘A’,4.5) C. f(‘A’,”123”) D. f((char)65,”123”) (3)已知函数f的原型为:void f(int &a,char *b); 变量s,t的定义是:int s; char t[]=”ABCD”;把s和t分别作为第一参数和第二参数来调用函数f,正确的调用语句是:__________ 。 A. f(&s,&t); B. f(&s,t); C. f(s,t); D. f(s,&t); (4)若指针p定义为const char *p="Luchy!"; 则[ ]。 A) p所指向的数据不可改变,p在定义时可以不初始化。 B) p所指向的数据不可改变,p在定义时必须初始化。 C) p本身不可改变,p在定义时可以不初始化。 D) p本身不可改变,p在定义时必须初始化。 (5)已知数组A和指针p定义为:int A[20][10],*p;,要使p指向A的首元素,正确的赋值表达式是[ ]。 A) p=&A 或p=A[0][0] B) p=A 或p=&A[0][0] C) p=&A[0] 或p=A[0][0] D) p=A[0] 或p=&A[0][0] (6)已知函数func的原形是 double func(doouble *pd,int &ri); 变量x和y的定义是 double x; int y; 把x和y分别作为第一参数和第二参数来调用函数func,正确的调用语句是[ ]。 A) func(x,&y); B) func(&x,y); C) func(&x,&y); D) func(x,y); (7)若指针p定义为char * const p="Luchy!"; 则[ ]。 A) p所指向的数据不可改变,p在定义时可以不初始化。 B) p所指向的数据不可改变,p在定义时必须初始化。

字符串与指针

一、 C语言中,为什么字符串可以赋值给字符指针变量 char *p,a='5'; p=&a; //显然是正确的, p="abcd"; //但为什么也可以这样赋值?? 问:一直理解不了为什么可以将字串常量赋值给字符指针变量,请各位指点! 答: 双引号做了3件事: 1.申请了空间(在常量区),存放了字符串 2. 在字符串尾加上了'/0' 3.返回地址 你这里就是返回的地址赋值给了 p 二、 char *p = “hello”; 上边的表达式为什么可以,而把p换成数组,然后再赋值就不行了 解释: 字符串常量"hello"出现在一个表达式中时,"hello"表达式使用的值就是这些字符所存储的地址(在常量区),而不是这些字符本身。 所以,可以把字符串赋值给指向字符的指针p,而不能把字符串赋值给一个字符数组。 char a[10] = “hello”; //这样可以,这种情况是c语言初始化所支持的 如果写成char a[10] 然后a = “hello” 这样就错误了。 同样是a数组,char a[10] = “hello”;这种是数组的初始化,和a[0] = ‘h’ a[1] = ‘e’…是一个道理 但是换成char a [10] 然后a = “hello”就不行了“hello”赋值的值是一个地址,而a虽然也有地址,但是这与指针是不一样的,指针的值是地址,而数组的值虽然也是地址,但是却是一个常量,所以不能给常量赋值。 三、 标题:对字符数组,字符指针,字符串常量 原帖地址:https://www.360docs.net/doc/7b17729318.html,/25069424.html

1.以字符串形式出现的,编译器都会为该字符串自动添加一个0作为结束符,如在代码中写 "abc",那么编译器帮你存储的是"abc\0" 2."abc"是常量吗?答案是有时是,有时不是。 不是常量的情况:"abc"作为字符数组初始值的时候就不是,如 char str[] = "abc"; 因为定义的是一个字符数组,所以就相当于定义了一些空间来存放"abc",而又因为 字符数组就是把字符一个一个地存放的,所以编译器把这个语句解析为 char str[3] = {'a','b','c'}; 又根据上面的总结1,所以char str[] = "abc";的最终结果是 char str[4] = {'a','b','c','\0'}; 做一下扩展,如果char str[] = "abc";是在函数内部写的话,那么这里的"abc\0"因为不是常量,所以应该被放在栈上。 是常量的情况:把"abc"赋给一个字符指针变量时,如 char* ptr = "abc"; 因为定义的是一个普通字符指针,并没有定义空间来存放"abc",所以编译器得帮我们 找地方来放"abc",显然,把这里的"abc"当成常量并把它放到程序的常量区是编译器 最合适的选择。所以尽管ptr的类型不是const char*,并且ptr[0] = 'x';也能编译 通过,但是执行ptr[0] = 'x';就会发生运行时异常,因为这个语句试图去修改程序 常量区中的东西。 记得哪本书中曾经说过char* ptr = "abc";这种写法原来在c++标准中是不允许的, 但是因为这种写法在c中实在是太多了,为了兼容c,不允许也得允许。虽然允许, 但是建议的写法应该是const char* ptr = "abc";这样如果后面写ptr[0] = 'x'的 话编译器就不会让它编译通过,也就避免了上面说的运行时异常。 又扩展一下,如果char* ptr = "abc";写在函数体内,那么虽然这里的"abc\0"被 放在常量区中,但是ptr本身只是一个普通的指针变量,所以ptr是被放在栈上的, 只不过是它所指向的东西被放在常量区罢了。