字符串的存储:
1.字符串就是一组字符组成,用双引号括起来表示,用字符’\0‘作为结束符(ASCII码也是0)
"hello world\0" 等价于 "hello world\0"
"hello" " world"等价于"hello world"
char e = '10'; 字符
char e = 10; 是char类型,是以ASCII码作为值赋给变量
char e = "10" 字符串 //并且无法保存,字符串不能如此定义
2.C语言存储字符串的方法
将字符串中每个字符的ASCII码按先后顺序存储在一段连续的内存中,每个字符占一个字节,最后用空字符,即ASCII码为0的字符结尾
字符串的表示
C语言表示字符串的方式
字符指针方式 字符指针不能修改任意字符,只能查看!!!! 不能pstr[2] = 'c';
char *pstr = "hello";//pstr保存字符串的首地址!!!!!注意是首地址!!!不是hello字符串!!!!
不能通过pstr修改指向的字符串,例如:pstr[1] = 'E'
printf("%s\n",pstr); //打印字符串只需传递一个首地址
字符数组方式 字符数组可以任意修改任意字符!!!
str[] = "abc";
str[] = {'a','b','c','\0'};
数组名即字符串首地址
可以用字面值初始化,也可以用{}初始化
用{}初始化需要手动显示注明结束符,否则就是一个数组
指针对应的字符串,其内存分配在常量区,不可更改
但是数组内存放的字符串,是数组自己定义并分配的内存空间,放在栈区,栈区的内存值是可以修改的
//字符串演示
//切记:当调用一个函数时,如果给这个函数传递一个字符串,实际本质是将这个字符串的首地址
//传递给这个函数
#include <stdio.h>
int main(void) {
printf("%s\n", "abcd\0"); //打印字符串占位符是:%s(s=string=字符串)
printf("%s\n", "abcd");
printf("%s\n", "1234\0abcd"); //1234
printf("abcd""12345\n"); //printf("abcd12345\n");
printf("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n");
printf("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n");
//字符指针变量和字符串的那点事儿
char *pstr = "abc"; //pstr保存字符串abc的首地址,并且字符串abc所在的内存区域只能读不能修改
printf("%s\n", pstr);//打印字符串只需传递一个首地址即可
printf("%c %c %c\n", pstr[0], pstr[1], pstr[2]);
printf("%d %d %d %d\n", *(pstr+0), *(pstr+1), *(pstr+2), *(pstr+3));
//pstr[2] = 'C'; //不可以修改,直接崩溃
//数组来表示字符串
char str[] = {'x', 'y', 'z', '\0'};//此时str既是数组又是字符串
printf("%s\n", str); //打印字符串
printf("%c %c %c\n", str[0], str[1], str[2]);
printf("%c %c %c\n", *(str+0), *(str+1), *(str + 2));
str[2] = 'Z'; //可以修改
printf("%s\n", str); //打印字符串
char str1[] = "mnab";
printf("%s\n", str1); //打印字符串
*(str1 + 2) = 'A'; //可以修改
printf("%s\n", str1); //打印字符串
printf("%lu\n", sizeof(str1));
return 0;
}
切记!!:当调用一个函数时,如果给这个函数传递一个字符串,实际本质是将这个字符串的首地址传递给这个函数
printf("%s","abcd")
char *pstr = "abcd";
char parr[] = "abcd"
printf("%s",pstr);prrintf("%s",parr);
printf("%c %c %c %c",pstr[0],pstr[1],pstr[2],pstr[3]); //parr也可以
printf("%d %d",*(pstr + 0),*(pstr+1)); //打印ASCII码值
字符串的输入
scanf("%s",); //按照字符串形式将输入的字符串保存到str数组中,碰到空格就结束
char* gets (char* s) ; /从标准输入读取一行字符串,读到换行符即返回,并将所读到的换行符置换为结尾空字符
字符串的输出
printf("%s",...);
int puts(const char *s);
向标准输出写入一行字符串,并追加一个换行符
示例:
//字符串输入和输出的标准库函数:scanf/gets/printf/puts
#include <stdio.h>
int main(void) {
char str[100] = {0}; //分配内存存储输入的字符串
//从键盘上输入字符串保存到数组str中
//scanf("%s", str);//按照字符串形式将输入的字符串保存到str数组中,碰到空格就结束
gets(str);//获取字符串保存到str
//打印字符串到显示器
//printf("%s\n", str);
puts(str);
return 0;
}
字符串函数
标准库提供一套专门针对字符串的函数
字符串头文件:
#include
字符串长度
unsigned int strlen(const char *s)
字符串拷贝
char* strcpy(char *dest, const char *src)
char* strncpy(char* dest, const char *src, unsigned int n)
字符串拷贝会覆盖数组中的原有字符串,且拷贝不可拷贝到字符指针上
字符串的拷贝如 char a[100] = "123456"
strcpy(a,"abcd");
此时打印的结果是abcd,5被abcd的结束符覆盖,但是内存中还保留6
字符串拼接
char *strcat(char *dest, const char *src)
char *strncat(char *dest, const char* src,unsigned int n)
字符串比较
int strcmp(const char *s1, const char* s2)
int strncmp(const char *s1,const char *s2, size_t n)
字符串相等时 回0;
前边大于后边时回正数
后边大于前边时回负数
字符串比较的是ASCII码值,从左往右第一个不同结果时ASCII码的比较
使用字符串函数时需要注意
1.所有字符串都必须以空字符结尾
2.字符串长度以char为单位且不包含结尾空字符
3.拷贝和连接的目标缓冲区必须可写且足够大
4.不能使用关系运算符比较字符串
示例:
//字符串处理标准C库函数
//你们内心一定要有个鉴定的信念:这些函数我也能自己编写!
#include <stdio.h>
#include <string.h>
int main(void) {
//1.strlen:获取字符串中有效字符的个数,不包含'\0'
char *p1 = "abcdefg";
printf("%lu, %lu\n", strlen(p1), strlen("abc"));
//2.strcat:将一个字符串拼接到另一个字符串的后面
char str[20] = "abc";//一次性分配20字节内存
strcat(str, "xyz");//将字符串xyz拼接到abc的后面
printf("%s\n", str);
char *p2 = "mn";
strcat(str, p2);//将p2指向的字符串mn拼接到abcxyz后面
printf("%s\n", str);
strncat(str, "1234", 2);//将字符串1234的前2个字符拼接到str对应的字符串后面
printf("%s\n", str);
//3.strcpy:字符串拷贝,将指定的字符串拷贝到指定的内存中
char str2[20] = "abcd";
strcpy(str2, "123456");//将字符串拷贝到str2数中
printf("%s\n", str2);
char *p3 = "abcd";
strcpy(str2, p3);//将p3指向的字符串abcd拷贝到str2数组中
printf("%s\n", str2);
for(int i = 0; i < sizeof(str2)/sizeof(str2[2]); i++) //调试打印
printf("%hhd ", str2[i]);
printf("\n");
strncpy(str2, "123456789", 7);//将字符串123456789前7个字符拷贝到str2数中
printf("%s\n", str2);
//4.strcmp:字符串比较,从左边到右边一个字符一个字符的比较,只要不相等或者字符串结束
//比较就立刻结束
int ret = 0;
ret = strcmp("abc", "abc");
printf("abc和abc比较的结果是:%d\n", ret);
ret = strcmp("abd", "abc");
printf("abd和abc比较的结果是:%d\n", ret);
ret = strcmp("abc", "abd");
printf("abc和abd比较的结果是:%d\n", ret);
ret = strncmp("abc", "abd", 2);
printf("abc和abd前2个字符比较的结果是:%d\n", ret);
return 0;
}
提问
编写resverse函数实现字符串的反转:“12345678” - -> "87654321"
//字符串反转
#include <stdio.h>
#include <string.h>
//pstr="a b c d e f g h" //字符
// 0 1 2 3 4 5 6 7 //下标
// i len-1-i
// i len-1-i
// i len-1-i
// i len-1-i
void reverse(char *pstr/*char pstr[]*/) { //pstr保存数组的首地址:char *pstr = str;
int len = strlen(pstr); //len=8, len/2=4
for(int i = 0; i < len / 2; i++) {
char c = pstr[i];
pstr[i] = pstr[len-1-i];
pstr[len-1-i] = c;
}
}
int main(void) {
char str[1024] = {0};
for(;;) {
gets(str); //从键盘上获取字符串保存到数组str
reverse(str); //进行反转
puts(str); //打印字符串
}
return 0;
}
提问:自己编写一个字符串比较函数
//自己编写一个字符串比较函数
#include <stdio.h>
//str1==str2,返回0
//str1>str2,返回>0
//str1<str2,返回<0
//str1 = "abc"
int my_strcmp(const char *str1, const char *str2) {
while(*str1) {
if(*str1 != *str2)
return *str1 - *str2;
str1++;
str2++;
}
return *str1 - *str2;
}
int main(void) {
int ret = 0;
ret = my_strcmp("abc", "abc");
printf("abc和abc比较的结果是:%d\n", ret);
ret = my_strcmp("abd", "abc");
printf("abd和abc比较的结果是:%d\n", ret);
ret = my_strcmp("abc", "abd");
printf("abc和abd比较的结果是:%d\n", ret);
return 0;
}