字符串常量可以赋值给一个字符指针或者一个字符数组,比如:
/*1*/char *str = “this is a string”;
/*2*/char str2[]= “this is a string”;
/*3*/char str3[100] = “this is a string”;
语句 1 将”this is a string”赋值给了字符指针 str。此时,str 的值为”this is a string”的第一
个字符的地址。实际上,”this is a string”这个常量字符串存储在 C 语言程序的常量区。而 str
即指向了存储这个常量字符串的首地址。
语句 2 会将常量区中的”this is a string”拷贝到数组里面。并且数组的长度将为”this is a
string” (包含’\0’)的长度。
语句 3 会将常量区中的”this is a string”拷贝到数组里面。并且数组的长度将为 100 个字
节。
语句 3 和语句 2 的区别是语句 2 没有指明数组的长度,那么数组的长度就是字符串的长
度。
对于上面的 3 个赋值表达式,分别使用 sizeof(占的内存空间的大小) 和 strlen(不包含结尾字符‘\0’的字符串个数) 的计算结果又是什么呢?
sizeof(str) = 为指针的长度,所以在 X86 上是 4,在 X64 上是 8。
sizeof(str2)=17。str2 数组的长度,但 str2 没有显示指出数组的长度,而是按照分配给它
的字符串的长度来分配。所以,值为 17。
sizeof(str3)=100。Sizeof 计算的是 str3 数组的长度,所以结果为 100。
strlen(str)=16。Strlen 计算的是字符串的字符个数(不喊’\0’)。
strlen(str2)=16。原因同上。
strlen(str3)=16。原因同上。
当然,也可以把字符串存放在动态分配的内存空间中。比如:
char *p = (char *)malloc(100);
if (p == NULL)
return;
memset(p, 0, 100);
strcpy(p, “hello world”);
这样,以 p 为首地址的内存中将存放着”hello world”这个字符串。
字符数组与字符串关系
char str1[]={‘h’,’e’,’l’,’l’,’o’,’ ‘,’w’,’o’,’r’,’l’,’d’};
char str2[]=”hello world”;
上面的语句定义了 2 个字符数组,其中 str1[]在初始化后,最后一个元素不是’\0’,而 str2[]
在初始化后,最后一个字符是’\0’,因此 str1[]不能当做字符串来处理,而 str2[]是可以当做
字符串来处理的,因为它最后一个字符是’\0’。
函数 strlen()用于计算字符串中的字符个数(不含结尾字符’\0’)
案例:输入一个字符串,将其逆序输出
#include <stdio.h>
#include <string.h>
char *str_reverse(char *str)
{
int n=strlen(str)/2;
int i=0;
char tmp=0; //????
//最右边的数和最左边的数交换
for(i=0;i<n;i++)
{
tmp=str[i];
str[i]=str[strlen(str)-1-i];
str[strlen(str)-1-i]=tmp;
}
return str;
}
int main()
{
char s[]="hello world!";
printf("str_reverse(s)=%s\n",str_reverse(s));
return 0;
}