1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > C语言.字符串 及string.h初步应用

C语言.字符串 及string.h初步应用

时间:2019-04-23 17:55:40

相关推荐

C语言.字符串 及string.h初步应用

一、字符

字符是用单引号 ’ ’ 括起来的单个普通字符或转义字符。

例:char c='A'; char c='\n';

二、字符串

在 C 语言中,字符串实际上是使用 null 字符 ‘\0’ 终止的“一维字符数组”(本质!)。

三、字符数组

下面的声明和初始化创建了一个 “Hello” 字符串。

例子: char A[10];//字符数组的赋值方法,三种赋值: char A[10] = {'h','e','l','l','o'}; --> 后面没有赋值的成员的值都是0char A[10] = {"hello"};-->等价于{'h','e','l','l','o','\0'} (本质)char A[10] = "hello";

注意:

1)整型不需要使用任何符号,字符使用单引号’’,字符串使用""。

2)重点:字符数组初始化后不能整体赋值!

四、字符指针

整型指针 --> 指向内容: int

二级指针 --> 指向内容: 指针

数组指针 --> 指向内容: 数组

函数指针 --> 指向内容: 函数

字符指针 --> 指向内容: char

例子:

char a = ‘h’;

char *p = &a; --> p就是字符指针 --> 指向某个字符

char *p = "hello"; --> 不是把整个字符串拷贝到指针变量,指针变量永远只能存放指针/地址

五、char*p="hello"和char p[]="hello"的区别

首先“hello”在程序开启的时候放在了内存的.rodata段,是一个常量区,是一个only-read只读区域。

char *p=“hello”是将’h’的地址赋给指针p,即p指向了常量区‘h’的地址。

char p[]="hello"是将常量区中的"hello"拷贝到数组p[]中。

其在内存中的情况如下:

例://例如,我们试图将字符串的'h'改为'k',其结果如上图char *p="hello";*p=‘k’;//错误,p指向常量区.rodata 'h'的地址,常量区的内容只读,无法修改;char p[]="hello";*p=‘k’;//正确,p[]在堆栈开辟连续内存并把"hello"从常量区复制过来;

注意:

1) p: 存放"hello"字符串首元素’h’的地址,

2) p是指向一个字符,不是指向一个字符串

3) 字符串在常量区存储时,以’\0’作为结束标志

细节补充1:

char *p="hello";char *q="hello";p和q的地址是一样的,编译器在处理的时候会把相同的字符串优化。

细节补充2:

“如果有空间”系统会在字符串后补‘\0’

反言之就是如果空间不够,系统就不能补了;

用strlen()测试下面字符串长度:char cc[5]="hello"; //结果:19(不确定) //空间不足补\0 {'h','e','l','l','o'}char cc[10]="hello"; //结果:5 //空间足够补\0 {‘h’,'e','l','l','o','\0','\0','\0','\0','\0'};char cc[]="hello"; //结果:5 //自适应 {‘h’,'e','l','l','o','\0'}//strlen()测字符串长度是到'\0'截止,第一张情况由于系统不能补'\0',则测的时候会一直寻找下去直到找到'\0'(null,0),所以其结果不定。到后面使用strcpy()同理,一定要注意开辟足够的内存空间例如存放"hello"应预留‘\0的位置’ char cc[6];

总结:

char A[10] = “hello”; --> 把常量区的字符串"hello"直接拷贝到栈空间A变量中(如果数组是局部变量)

char *p = “hello” --> 把常量区的字符串"hello"的首元素的地址存储在指针变量p中

六、strlen()

原型:

*size_t strlen(const char *s);

功能: 给一个字符串的起始地址s,不断往后计算,直到遇到\0为止就停止计算!

返回值:s指向的字符串对应的字符个数*

问题①:

//strlen()的用法以及和sizeof()的区别char B[] = "helloworld";char A[100] = "helloworld";char *p = "helloworld";printf("sizeof(A) = %d\n",sizeof(B));//11printf("sizeof(A) = %d\n",sizeof(A));//100printf("sizeof(p) = %d\n",sizeof(p));//4printf("strlen(A) = %d\n",strlen(B));//10printf("strlen(A) = %d\n",strlen(A));//10printf("strlen(p) = %d\n",strlen(p));//10//由char B[]可知'\0'也占一个空间,但是测字符串的时候不会算进去。//由char A[100]可知,后面全补0,一样会占内存空间,但不会算在字符串长度上。//sizeof(p)测的是'h'的地址,相当于sizeof(char *),任何指针都是占4个字节(32位系统机器位长)

问题②:

int main(){char a[7]="a0\0a0\0";char b[7]="a0\0asds";char c[7]="a0\aasds";char d[7]="a0\aaa\0";printf("%d \n",strlen(a)); //2printf("%d \n",strlen(b)); //2printf("%d \n",strlen(c)); //12printf("%d \n",strlen(d)); //5}//'\0'结束 结果2//‘\0’结束 结果2//'\a'转义字符,算一个字符 总共7个字符 c[7]没空间补'\0' 其结果为12(不确定)//‘\a’转义字符 ,‘\0’结束,一共5个字符 结果5

补充-关于转义字符:

总结:

1)strlen()传首地址进来,返回长度;

2)strlen()直到‘\0’结束,要考虑是否有‘\0’(空间是否够补);

3)转义字符算一个字符;

七、strcmp()

int strcmp(const char *s1, const char *s2);

int strncmp(const char *s1, const char *s2, size_t n);

功能:

比较两个字符串是否一致;

参数:

s1与s2都是需要进行对比的字符串的首元素地址

n: 只匹配前n个字节

返回值:

s1与s2匹配: 0

s1与s2不匹配: 非0 (实际可能负数或正数,但一般用不到,知道非0就行)

//Demochar A[100] = "helloworld";char *p = "hello";//if(A == p)//错误if(strncmp(A,p,5) == 0) //正确{printf("ok!\n");}

注意:

1 )strcmp也是基于strlen的基础上,所以若果不够空间存’\0’也会导致越界对比,导致字符串不匹配;

八、strcpy()

原型:

char *strcpy(char *dest, const char *src);

char *strncpy(char *dest, const char *src, size_t n);

功能:

拷贝字符串到某段内存中

参数:

dest: 需要把字符串拷贝到的空间的起始地址,空间必须足够大

src: 需要拷贝的字符串起始地址

n: 需要的前n个字节 ,需要src指向的内容总长度

返回值:

指向dest这个区域的指针

char a[]="hello";char b[]="ab";strcpy(a,b);//执行后a里面是:{'a','b','\0','l','o','\0'}printf("%s",a);//打印 ab//printf("%c",a+3)//打印 l

注意:

1)保证被拷贝的空间足够,否则会导致越界

2)strcpy会把’\0’也拷贝过去

3)n指定可以实现追加字符串功能

经验:

① 常用于字符数组初始化后赋值:

char A[100];

A[100] = “gec123456” ; //错误

strcpy(A,“gec123456”);//正确

②malloc()申请堆空间,要用strcpy把字符串赋值过去。

九、strcat()

功能:追加字符串

十、关于数组清零的几种常用方式

1.定义数组时初始化0

char s[50]={0}; – 初始化时,小于开辟的长度,后面自动补0

2.清空某段内存空间 – bzero() –

#include <strings.h>

void bzero(void *s, size_t n);

s: 需要清零的内存空间首地址

n:需要清零的字节数

没有返回值

char str[50]; bzero(str,50);

3.内存初始化 --memset()–

#include <string.h>或#include <memory.h>

void *memset(void *s, int ch, size_t n);

函数解释:将s中当前位置后面的n个字节 (typedef unsigned int size_t )用 ch 替换并返回 s 。

功能:作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法 。

char str[50];memset(str,0,sizeof(str));

十一、开发经验

以上几个函数在开发中会使用到的场景:

1)write()/send() – 确定某些数据的总字节数 – strlen()

2)strcmp() – 检索数据的正确与否 /登录密码,检索某个特征值

3)strcpy() – 给某些字符数组赋值(数组初始化后不能整体赋值)

char A[100];

A[100] = “gec123456” ; //错误

strcpy(A,“gec123456”);//正确

4)strcat() – 拼接字符串,仅限于追加功能 – 后期使用sprintf()代替strcat()

更多:/intelwisd/p/8299738.html

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。