当前位置:首页 » 《休闲阅读》 » 正文

【c语言篇】--字符串和内存函数

10 人参与  2024年10月28日 19:20  分类 : 《休闲阅读》  评论

点击全文阅读


目录

前言

一、函数介绍

1.1 strlen函数

1.2strcpy函数

1.3strcat 函数

1.4 strcmp函数

1.5 memcpy函数

1.6memmove 函数

二、自定义类型--结构体

2.1结构体声明

2.2结构体变量的定义和初始化

2.3结构体传参

三、位段

3.1认识位段

3.2 位段的内存分配

四、枚举

4.2为什么要用枚举?

4.3枚举的使用

总结



前言

上篇我们学习了指针进阶,今天我们来学习字符串、结构体、位段、枚举等。

一、函数介绍

1.1 strlen函数

先看如下实例代码:

int my_strlen(const char* str){assert(str!=NULL);if (*str != '\0'){return 1 + my_strlen(str + 1);}elsereturn 0;}int main(){char a[] = "abcde";int len = my_strlen(a);printf("%d", len);return 0;}

strlen是求字符串长度,统计\0之前出现的字符个数

1.2strcpy函数

char* strcpy (char *destination,const char *source)

strcpy 函数将source值 拷贝给 desination,拷贝的前提是目标空间足够大,以确保能放下。长度不受限制。

1.3strcat 函数

char* strcat (char *destination,const char *source)

strcat函数j将右边的值追加到左边值的尾部,长度不受限制。

1.4 strcmp函数

int strcmp(char* str1,char* str2)

strcmp函数,比较俩字符串大小,长度不受限制。以上四组就是我们常见的、常用的一些字符串函数下面简单介绍些其他的

   int strncmp(const char*str1,const char * str2, size_t num);

   比较出现另个字符不一样或者一个字符结束或者num个字符全部比较完

同理,有strncmp函数,也有strncat、strncpy。

字符分类函数:

函数如果他的参数符合下列条件就返回真
iscntrl任何控制字符
isspace空白字符:空格' ',换页’\f',换行‘\n’,回车‘\r’,制表符'\t'或者垂直制表符'\v'
isdigit十进制数字0~9
isxdigit十六进制数字,包括所有十进制数字,小写字母a~f,大写字母A~F
islower判断小写字母
isupper判断大写字母
isaipha字母a~z或A~Z
isalnum字母或者数字标点符号a~z,A~Z,0~9
ispunct标点符号,任何不属于数字或者字母的图形字符(可打印)
isgraph任何图形字符
isprint任何可打印字符,包括图形字符或空白字符

1.5 memcpy函数

void* memcpy(void* destination,const void* source,size_t num)

memcpy函数,从源头指向的内存块拷贝固定字节的数据到目标指向的内存块,模拟代码实现如下:

void* my_memcpy(void* dest, void* src,size_t num){void* ret = dest;assert(dest && src);while (num--){*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}return ret;}int main(){int arr[] = { 1,2,3,4,5,6,7,8,9,10 };int arr2[10] = { 0 };my_memcpy(arr2, arr+1, 20);for (int i = 0; i < 10; i++){printf("%d\n", arr2[i]);}return 0;}

使用了模拟memcpy函数my_memcpy将arr数组下标为1的前20字节(即前5个整形)拷进arr2数组中

1.6memmove 函数

void* memmove(void* destination,const void* source,size_t num)

memmove函数功能是:从源头指向的内存块拷贝固定字节的数据到目标指向的内存块,并且源头的内存块与目标内存块可以重叠(最后一部分memmove与memcpy最大的区别)

具体实例如下:

#include<stdio.h>#include<string.h>int main(){int arr[] = { 1,2,3,4,5,6,7,8,9,10 };memmove(arr+2, arr, 16);for (int i = 0; i < 10; i++){printf("%d\n", arr[i]);}return 0;}

memmove函数将arr前四个元素1,2,3,4拷贝给arr下标为3的四个数(即3,4,5,6)。

二、自定义类型--结构体

2.1结构体声明

结构是一些值的集合,这些值是成员变量,结构的每个成员可以是不同类型的变量

struct stu {
    char name[20];
    int age;

}s1,s2;  //分号不能少

s1,s2 是两个结构体变量,全局变量,

匿名结构体类型

struct {int a;char b;float c;}x;struct {int a;char b;float c;}a[20],*p;

上面两个结构体声明过程中少了个结构体标签,只有个单一的struct。其实这俩个声明是完全不一样的两个类型。

2.2结构体变量的定义和初始化

有了结构体,定义变量及初始化如下;

struct point {  //类型的声明int x;int y;}p1 = { 10,20 };//声明类型的同时定义变量p1及初始化//初始化:定义变量的同时赋值初始化struct point s2 = { 1,0 };

上面这是结构体最简单的初始化,我们再看一看结构体嵌套下的初始化(即就是一个结构体里包含着另一个结构体,示例如下:

struct S {int num;char ch;struct point p;float d;}n1={1,'w',{2,3},3.4f}; //结构体嵌套初始化struct S s = { 100,'ww',{3,4},3.45f }; //结构体嵌套初始化

嵌套结构体使用时要用到{ }符号。

2.3结构体传参

示例代码如下:

struct S {int data[20];int num;};struct S s = { {1,2,3,4},1999 };void print1(struct S s) {printf("%d\n", s.num);}void print2(struct S* ps){printf("%d\n", pe->num);}int main(){printf1(s); //传结构体print2(&s); //传地址}

print1和print2都是传参,哪个更好些?答案是:首选print函数,

函数传参的时候,参数需要压栈,会有时间空间上的系统开销。

如果传递一个结构体对象的时候,结构体过大,参数压栈的系统开销比较大,所以会导致性能的下降。

三、位段

3.1认识位段

先看一段代码:

struct A {int _a : 2; //二进制位int _b : 4;int _c : 10;};

在上述代码中,A表示一个位段类型,_a 表示2个二进制位,尾端跟结构体类似,功能跟结构体一样,但比结构体更节省空间

3.2 位段的内存分配

位段的成员可以是 int    unsigned int   signed int  或者char(属于整形家族)类型

位段的空间上是按照需要以四个字节(Int)或者1个字节(char)方式开辟的。

位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段

四、枚举

4.1枚举类型的定义,直接上代码:

enum Day {mon,Tues,wed,Thur,Fri,sat,sun,};

枚举其实就是列举,上述代码中,定义的enum Day就是枚举类型,{ }中的内容是枚举类型的可能取值,也叫枚举常量

这些取值都是有值的,默认从0开始,依次递增1,当然在定义的是时候,也可以赋值初值,如:

enum SEX {MALE = 2,DASE=4,SECRE=5,};

4.2为什么要用枚举?

我们可以用#define 定义常量,为什么非要用枚举?

主要有以下几点:

增加代码的可读性和可维护性

和#define 定义的标识符比较,枚举有类型检查,更加严谨。

防止命名污染(封装)

便于调试

使用方便,一次可以定义多个常量

4.3枚举的使用

直接上代码演示:

enum color { //颜色RED=1,GREEN=2,BLUE=4};enum color clr = GREEN; //只能枚举常量给枚举变量赋值,才不会出现差异

上述代码中最后一行执行了使用枚举类型,

总结

提上就是本片所有内容,希望这篇内容对大家有所帮助。

欢迎大家评论点赞,大家的支持是我前进的动力


点击全文阅读


本文链接:http://zhangshiyu.com/post/179204.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1