[题集]指针与字符串
下面我们开始来做题:
调试题:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
char* str1 = "Learning pointer now!";
//将指针str1指定到learning....字符串的首地址
char str2[] = "Go ahead";
//将Go ahead字符串存入str2数组中,数组名为字符串的首地址
char str3[20];
char* str4;
str3 = "I want to buy a iPhone";
printf("C or C++");
scanf("%s", str4);
printf("\n%s\n",str1 );
printf("\n%s\n",str2 );
printf("\n%s\n",str3 );
printf("\n%s\n", str4);
system("pause");
return 0;
}
编译器在编译的时候报错,只报了一处:
因为数组名不可赋值,数组是指针常量,它所包含的是数组的首地址,不能指定一个字符串给它,只能在定义时赋值:
这时字符串会依次存入数组中。
再次运行时,报错了,指针是一个指针变量,它不可指向未知的地址
我们只需要手动给str4分配好内存即可解决该问题:
分配了五十个char*大小的地址给指针
修改后的代码:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
char* str1 = "Learning pointer now!";
//将指针str1指定到learning....字符串的首地址
char str2[] = "Go ahead";
//将Go ahead字符串存入str2数组中,数组名为字符串的首地址
char str3[30] = "I want to buy a iPhone";
char* str4 = (char*)malloc(50);
printf("C or C++\n");
scanf("%s", str4);
printf("\n%s\n",str1 );
printf("\n%s\n",str2 );
printf("\n%s\n",str3 );
printf("\n%s\n", str4);
system("pause");
return 0;
}
修改后的运行结果:
第二题:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
char* s = "iPhone";
char* t;
printf("复制前\n");
printf("s=%s\nt=%s\n", s, t);
strcpy(t, s);
printf("复制后\n");
printf("s=%s\nt=%s\n", s, t);
system("pause");
return 0;
}
编译器报错:
*t是一指针变量,它没有连续性的地址,所以不能完成复制动作
解决方案:
- 将t改为数组
- 动态分配t一片内存
复制前t为一片垃圾内存,所以输入乱码
程序实战:
1.strchr(str,'d')函数是寻找d字符出现在str字符串中的地址,编写模拟此函数的程序,思路如下:
- 定义一个带d的字符串,指定给一指针(数组)
- 利用函数将此字符串地址传入形参内
- 循环遍历,依次判断地址内的字符是否为d
- 如果是,返回d的地址,如果不是,则继续循环
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char seek(char*, char);
int main()
{
char* s = "Congratulation";
char c = 'g';
strchr(s, c);
printf("%x\n", strchr(s, c));
printf("%x\n", seek(s, c));
system("pause");
return 0;
}
char seek(char* s, char b)
{
while (*s != '\0')
{
if (*s == b)
{
return s;
}
s++;
}
return 0;
}
运行结果:
整段字符串是一个拥有14个字符包括一个空字符,总长度为15个char类型,一个char类型占两个字节
首地址为4c,g是在首地址上加了3个char字节长度,
第三题:
stricmp(t,s)函数是比较t,s两个字符串,且忽略大小写的诧异,试编写自定义函数模拟此操作
大小字母ASCII值相差32,则若忽略大小写,可全部转换为大写或小写进行比较
- 定义两个字符串
- 利用两个循环遍历字符串每个字符
- 判断每个字符是否处在大(小)写字符范围内
- 如果处在,则+(-)32转换为相同大(小)写
- 在不为\0字符的前提下利用循环判断两字符是否相等
- 若相等则返回0,不相等则返回两字符相减的结果
#define _CRT_SECURE_NO_WARNINGS
#define _CRT_NONSTDC_NO_DEPRECATE
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void stringcompare(char*, char*);//转换函数
char stringcompare2(char*, char*);//比较函数
int main()
{
int v1, v2;
char s3[] = "Axuan Is loSer";
char s4[] = "C am iS DiaOsi";
char* s1 = s3;
char* s2 = s4;
printf("使用库函数:\n");
v1 = stricmp(s3, s4);
if (v1 == 0)
printf("S1=S2\n");
if (v1 > 0)
printf("S1>S2\n");
if (v1 < 0)
printf("S1<S2\n");
printf("使用自定义函数:\n");
stringcompare(s1, s2);
printf("转换后:\ns1=%s\ns2=%s\n", s1, s2);
v2 = stringcompare2(s1, s2);
if (v2 == 0)
{
printf("S1=S2\n");
}
else if (v2 > 0)
{
printf("S1>S2\n");
}
else
{
printf("S1<S2");
}
system("pause");
return 0;
}
void stringcompare(char* x, char* y)
{
while (*x != '\0')
{
if (*x >= 'A' && *x <= 'Z')
{
*x += 'a' - 'A';
}
x++;
}
while (*y != '\0')
{
if (*y >= 'A' && *y <= 'Z')
{
*y += 'a' - 'A';
}
y++;
}
}
char stringcompare2(char* x, char* y)
{
while (*x == *y)
{
if (*x == '\0')
{
return 0;
}
x++;
y++;
}
return *x - *y;
}
在这段代码的时候,由于转换函数内需要进行指针取他值运算,则会出现内存写入错误,原因就是因为指针为变量,它不是一段固定连续性的内存
所以需要指向数组来操作。
在
转换函数内,它将所有大写字符都加上了32,则全部转换为小写
我们看一下运行结果:
那么书上的答案更加简便,我们看下书上的答案代码:
#define _CRT_SECURE_NO_WARNINGS
#define _CRT_NONSTDC_NO_DEPRECATE
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char stringcompare(char* ,char*);//比较函数
int main()
{
int v1, v2;
char *s1 = "Axuan Is loSer";
char *s2 = "I am iS DiaOsi";
printf("使用库函数:\n");
v1 = stricmp(s1, s2);
if(v1==0)
printf("S1=S2\n");
if(v1>0)
printf("S1>S2\n");
if(v1<0)
printf("S1<S2\n");
printf("使用自定义函数:\n");
v2 = stringcompare(s1, s2);
if (v2 == 0)
{
printf("S1=S2\n");
}
else if (v2 > 0)
{
printf("S1>S2\n");
}
else
{
printf("S1<S2\n");
}
system("pause");
return 0;
}
char stringcompare(char*x, char*y)
{
for (; *x == *y || *x - 32 == *y || *x + 32 == *y;x++,y++)
{
if (*x == '0')
{
return 0;
}
}
return *x - *y;
}
答案就是在:
这段循环条件上,拟了大小写转换,直接比较,比我们自己的代码更加简洁!