当前位置:网站首页>C语言字符串——关于指针
C语言字符串——关于指针
2022-08-02 14:02:00 【iccoke】
c字符串
我们知道在关于字符串的操作函数很多都包含在头文件#include<string.h>中,例如计算字符串长度的函数strlen。今天我们们用自己的语言来实现一下关于字符串的复制,连接,和比较
strcmp()字符串比较函数的指针实现
字符串串比较的时候实际上是ASC||值的比较,因此用关系运算符比较即可
int my_strcmp(char* str, const char* src) {
assert(*str != NULL && *src != NULL);
while (*str = *src) {
if (*str = '\0') {
break;
}
str++;
src++;
}
if (str > src) {
return 1;
}
else if (str < src) {
return -1;
}
else {
return 0;
}
}
这里我们发现了在跳出循环后的代码冗余,我们可以用一个三目运算符进行优化
int my_strcmp(char* str, const char* src) {
assert(*str != NULL && *src != NULL);
while (*str = *src) {
if (*str = '\0') {
break;
}
str++;
src++;
}
if (str == '\0'&& src == '\0') {
{return 0; }
return str > src ? 1:-1;
}
经过这样的判断我们就可以得到如果str=src返回0,str>src返回1,str<src返回-1。
strcat(),字符串连接函数
我们这里可以直接使用指针访问到字符串的尾部在加上需要连接的字符串或者我们使用指针移位的方式操作,同时要注意连接前的字符串数组的大小应该要大于连接后的大小。
void my_strcat(char* p, char* q) {
assert(p != NULL && q != NULL);
int i = strlen(p); int j = 0;
while (*(q + j) != '\0') {
*(p + i) = *(q + j);
i++; j++;
}
*(p + i) = '\0';
}
char* my_strcat2(char* p, const char* q) {
while (*p++ != '\0');
while (*q != '\0') {
*p++ = *q++;
}
*p = '\0';
}
最后比较重要的是字符串默认以\0结尾,所以不管哪种方式,我们都要在尾部加上\0。
strcpy(),字符串拷贝函数,同上一个函数一样我们在最后都需要加上字符串的默认结尾\0
void my_strcpy(char* p, char* q, int len) {
assert(p != NULL && q != NULL);
if (p <= q && p >= q + len - 1) {
for (int i = 0; i < len;) {
*(q + i) = *(p + i);
i++;
}
}
else {
for (int j = len - 1; j >= 0;) {
*(q + j) = *(p + j);
j--;
}
}
}
char* my_strcpy(char*q,const char*p) {
assert(*p != NULL && *q != NULL);
while (*p != '\0'){
*q = *p;
q++;
p++;
}
*q = '\0';
}
指针习题中的问题
1. 即使不进行强制类型转换,在进行指针赋值运算时,指针变量的基类型也可以不同
这句话显然是错误的,基类型也就是指针变量的基本类型,它反映了指针变量可以存储变量大小和+1能力,比如一个char*p int *s p+1就是加了sizeof(char) ,而s+1就加了sizeof(int),所以在对指针进行赋值运算时,指针变量的基类型不能不相同
2.设变量p是一个指针变量,则语句p=0;是非法的,应该使用p=NULL;
在c语言中,这两者其实是相同的,0就是NULL,NULL也就是0
3. 指针变量之间不能用关系运算符进行比较
这个也是错误的,指针变量是可以进行关系运算符的比较的。但是同一个变量但是在不同的情况下的情况也不同
const char*s="hello";
const char*p="hello';
那么s和p的地址实际上是相同的
因为这属于字符串常量,存储的时候是存储在数据区,s会先在常量池中寻找是否有"hello",如果没有就在常量池中加入,p就会找到”hello“存储的地方并且拿到它的地址,所以s和p的地址实际上是相同的
char arr[]=”hello“;
char brr[]="hello";
在这里这两者的地址就不是相同的,因为他们是在栈中申请一块连续的内存空间存储hello\0,而我们知道,栈是从高地址往低地址分配内存空间,那么arr的地址就和brr的地址不相同
4.float a[10], x;语句 a = &x; 是非法的
这个是正确的,这就涉及到了c语言中的函数赋值问题
例如 int arr[];
int brr[10]={1,2,3,4,5};
arr[]=brr[10];
关于数组的赋值不能只有简单的等号来进行
5.C、 可以取一个指针变量的地址赋给本指针变量,这样就使得指针变量指向自身
这个选项是错误的
例如 int *p
p=&p,这是将一个二级指针赋给一个一级指针语法上就是有问题的。
6. 指针变量所占内存的大小与其类型有关,char型指针变量只占1个字节,double型指针变量占8个字节
这个是错误的,指针的大小只和操作系统有关
7.以下不能将s所指字符串正确复制到t所指存储空间的是( )。
A、 for(i=0,j=0;t[i++]=s[j++]; );
B、 for(i=0;t[i]=s[i];i++);
C、 while(*t=*s){t++;s++;}
D、 do{*t++=*s++;}while(*s );
这个题的正确选项是D选项,因为do while是先执行在判断,这就会使其先加一再判断,就会丢失字符串末尾的\0。
8.double a[10] ,*s=a;
以下能够代表数组元素a[3]的是( )。
A、 (*s)[3]
B、 *(s+3)
C、 *s[3]
D、 *s+3
在这个题目条件下就是选择b选项
但是如果改变一下题目条件
double (*s)[4]={1,2,3,4,5,6,7,8}
(s*)[4]=a;
中的a[0][3]元素应该如何选择首先找到他的地址*(a+0)+3,在对地址解引用*(*(a+0)+3)也就是*(*a+3),将a换成s,也就是*(*s+3),那么他就和A代表的值是一样的。
边栏推荐
- drf源码分析与全局捕获异常
- verilog学习|《Verilog数字系统设计教程》夏宇闻 第三版思考题答案(第十四章)
- Unit 4 Routing Layer
- Flask-SQLAlchemy
- [ROS]roscd和cd的区别
- (ROS) (03) CMakeLists. TXT, rounding
- Building and getting started with the Flask framework
- Web Design (Beginners) [easy to understand]
- 跑跑yolov5吧
- Visual Studio配置OpenCV之后,提示:#include<opencv2/opencv.hpp>无法打开源文件
猜你喜欢
Deep learning framework pytorch rapid development and actual combat chapter3
redis延时队列
Creating seven NiuYun Flask project complete and let cloud
Sentinel源码(三)slot解析
C语言sizeof和strlen的区别
paddleocr window10 first experience
Raj delivery notes - separation 第08 speak, speaking, reading and writing
第十单元 前后连调
The specific operation process of cloud GPU (Hengyuan cloud) training
MarkDown syntax summary
随机推荐
使用云GPU+pycharm训练模型实现后台跑程序、自动保存训练结果、服务器自动关机
Go语言初始
如何自定义feign方法级别的超时时间
[ROS]roscd和cd的区别
Flask-SQLAlchemy
The specific operation process of cloud GPU (Hengyuan cloud) training
Building and getting started with the Flask framework
Flask framework in-depth two
How to solve mysql service cannot start 1069
EasyExcel 的使用
paddleocr window10初体验
jwt(json web token)
The 2nd China Rust Developers Conference (RustChinaConf 2021~2022) Online Conference Officially Opens Registration
verilog学习|《Verilog数字系统设计教程》夏宇闻 第三版思考题答案(第九章)
鼠标右键菜单栏太长如何减少
[ROS](06)ROS通信 —— 话题(Topic)通信
STM32 (F407) - stack
第八单元 中间件
网页设计(新手入门)[通俗易懂]
MobileNet ShuffleNet & yolov5替换backbone