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 printf("%c", str[i]); } printf("\n"); return 0; } 运行结果: hello world ! hello world ! 字符数组归根结底还是一个数组,上节讲到的关于指针和数组的规则同样也适用于字符数组。更改上面的代码,使用指针的方式来输出字符串: #include #include #include int main() { char str[] = "hello world !"; char *pstr = str; int len = strlen(str), i; //使用*(pstr+i) for (i = 0; i printf("%c", *(pstr + i)); } printf("\n"); //使用pstr[i] for (i = 0; i printf("%c", pstr[i]); } printf("\n"); //使用*(str+i) for (i = 0; i printf("%c", *(str + i)); } printf("\n"); system("pause"); return 0; } 运行结果: hello world ! hello world ! hello world ! 除了字符数组,C语言还支持另外一种表示字符串的方法,就是直接使用一个指针指向字符串,例如: char *str = " hello world !"; 或者: char *str; str = " hello world !"; 字符串中的所有字符在内存中是连续排列的,str 指向的是字符串的第0 个字符;我们通常将第0 个字符的地址称为字符串的首地址。字符串中每个字符的类型都是char,所以str 的类型也必须是char *。 下面的例子演示了如何输出这种字符串: #include #include #include int main() { char *str = "hello world !"; int len = strlen(str), i; //直接输出字符串 printf("%s\n", str); //使用*(str+i) for (i = 0; i printf("%c", *(str + i)); } printf("\n"); //使用str[i] for (i = 0; i printf("%c", str[i]); } 实验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 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"); 彻底搞定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人为加入\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]); 第七章字符数组与字符串 【题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’, 一、选择题 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 [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). 函数参数列表中的以数组类型书写的形式参数,编译器把其解释为普通的指针类型 第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 在初学习C语言时,对于指针是最容易让人迷糊的,尤其对于指针数组,而且是指向字符串的指针数组,恐怕就更难理解了。下面本人给出一个例子,详细讲解指向字符串的指针数组的使用情况。希望给予学习C的朋友一点帮助。 下述程序执行后,输出结果是什么? #include 最近工作之余,发现了两个自己在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、C++字符串指针(指向字符串的指针) C语言中没有特定的字符串类型,我们通常是将字符串放在一个字符数组中,这里我们来演示一下: #include C语言程序设计实验答案数组、指针与字符串
C语言字符串指针问题
指向指针的指针——彻底搞定C指针
C语言字符串的输入和输出
第七章字符数组与指针练习题参考答案
C语言指针习题__附答案[1]
指针经典练习题及答案
字符数组,字符指针,sizeof,strlen总结
第8章 指针-3字符数组和字符指针 - 字符串的表示与存储
指向字符串的指针数组
字符串指针和字符数组,静态全局、静态局部、全局和局部变量区别,字符串常量和字符串变量,程序的内存分配
C、C++字符串指针(指向字符串的指针)