概述
关于C语言中 字符串 指针 和字符数组的理解
- 字符串常量和字符数组
- 字符串常量
- 字符数组
- 为什么要把字符串常量和字符数组拿出来讲呢?
- 指针
- 为什么???
- 最后我们重新来理解一下下面两种定义的区别
- 扩展
字符串是一种非常重要的数据类型,但是C语言不存在显式的字符串类型,C语言中的字符串都以字符串常量的形式出现或存储在字符数组中。同时,C 语言提供了一系列库函数来对操作字符串,这些库函数都包含在头文件 string.h 中。
字符串常量和字符数组
C 语言虽然没有字符串类型,但是 C语言提是存在字符串这个概念的,也就是字符串常量:以 NUL(’ ’) 字节结尾的 0 个或多个字符组成的序列。
字符串常量
字符串常量是不可被修改的,一般用一对双引号(" “)括起的一串字符来表示字符串常量,如:“Hello!”、”aWarning!a"、“123abcn”。
字符串常量可以为空,如""就是一个空的字符串常量,但是即使为空,还是存在一个终止符 NUL 的。(在 C 语言中,常用转义字符 来表示 NUL)
重点:" " 双引号引用起来的东西 就是 字符串常量, 存储在静态存储区。 常量 是不可以修改的。
字符数组
用于存放字符的数组称为字符数组。在 C 语言中,除了字符串常量外,其他所有字符串都必须存储于字符数组或动态分配的内存中。定义一个字符数组和定义一个普通数组一样,不同的是字符数组中存放的是字符数据而已:char charArray[] = {‘H’,‘e’,‘l’,‘l’,‘o’}; // 声明并初始化一个字符数组。
这句话定义并初始化了一个字符数组 charArray。这个数组的长度实际上为 6 ,因为会自动添加一个字符串结束符 ‘ ’。
重点:字符数组是可以修改的 它不是常量。
为什么要把字符串常量和字符数组拿出来讲呢?
为什么要把字符串常量和字符数组拿出来讲呢?主要是要明白:字符串常量 是常量 在静态存储区 是不可以修改的;而字符数组 是动态分布在内存中的 ,是可以被修改的。
这样解释也许你还是不太理解。知道是这么回事 ,但不知道这具体有什么作用。这就要涉及到另一个概念——指针。
指针
指针,是C语言中的一个重要概念及其特点,也是掌握C语言比较困难的部分。指针也就是内存地址,指针变量是用来存放内存地址的变量,不同类型的指针变量所占用的存储单元长度是相同的,而存放数据的变量因数据的类型不同,所占用的存储空间长度也不同。有了指针以后,不仅可以对数据本身,也可以对存储数据的变量地址进行操作。
关于什么是指针等问题 我不做过多的阐述。
下面我们就来解答上面的疑问,请看下面的例子:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void mystrlwr(char *strs)
{
puts(strs);
printf("%pn",strs);
printf("%dn",strlen(strs));
printf("strcmp=%dn",strcmp(strs,"MY LovE"));
while(*strs){
printf("%cn",*strs);
if(*strs >= 'A' && *strs <= 'Z'){
printf("++++++n");
*strs = *strs + 'a' - 'A';
printf("------n");
}
strs++;
}
printf("%pn",strs);
}
int main()
{
char strs[] = "MY LovE";
char *pstrs;
pstrs = strs;
puts(pstrs);
printf("%pn",pstrs);
printf("%dn",strlen(pstrs));
mystrlwr(pstrs);
printf("=====================n");
printf("%pn",pstrs);
puts(pstrs);
}
上面的程序很简单 就是自己写的一个 strlwr 函数,目的在于把字符串中的大写字母转换成小写字母。
这样运行没有问题。
但是我们学过指针,在C语言中 我们经常使用指针来定义字符串,例如:
上面的:
char strs[] = "MY LovE";
char *pstrs;
pstrs = strs;
在这里我们可以这样理解,先定义了一个字符数组strs[],并且给它赋了初值"MY LovE";然后我们定义了一个字符指针pstrs,然后将字符数组的首地址strs 放在了定义的字符指针pstrs中。(数组的变量名就是数组第一个元素的地址,这一点不能理解的自己去看有关于数组的部分,在一定程度数组名完全理解成一个地址)
上面的程序 我们可以简写一下:
char strs[] = "MY LovE";
char *pstrs = strs;
这样也没问题。
重点:
有时候我们很懒,我们注意到 我们完全可以将 定义数组strs[]的部分进行省略。
就写成了下面这样:
char *pstrs = "MY LovE";
写成 这样 以后 我们输出puts(pstrs);查看结果。我们发现结果就是我们想要的 字符串。一些都看似合理没有任何问题。
于是我们代码就改写成了下面这样:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void mystrlwr(char *strs)
{
puts(strs);
printf("%pn",strs);
printf("%dn",strlen(strs));
printf("strcmp=%dn",strcmp(strs,"MY LovE"));
while(*strs){
printf("%cn",*strs);
if(*strs >= 'A' && *strs <= 'Z'){
printf("++++++n");
*strs = *strs + 'a' - 'A';
printf("------n");
}
strs++;
}
printf("%pn",strs);
}
int main()
{
char *pstrs = "MY LovE";
puts(pstrs);
printf("%pn",pstrs);
printf("%dn",strlen(pstrs));
mystrlwr(pstrs);
printf("=====================n");
printf("%pn",pstrs);
puts(pstrs);
}
然后我们去编译,没问题,编译成功,然后我们就运行。但是这时候程序就出错了!!!
为什么???
运行程序,我们就会发现,程序停在了,语句:
*strs = *strs + 'a' - 'A';
停在了这里。为什么?
为了更明确出现问题的原因,我们可以先定义一个局部的字符变量,然后将 *strs + ‘a’ - ‘A’ 赋值给它,打印结果。
char str;
str = *strs + 'a' - 'A';
printf("str = %dn",str);
结果没有问题,然后我们将
*strs = *strs + 'a' - 'A';
修改为:
*strs = str;
然后运行。结果程序又停在了这里。
说明问题就是对*str进行赋值这里出错了。
这就是为什么我们为什么要讲上面的内容。
怎么理解这句话,首先我们理一理指针strs是存的谁的地址,是pstrs ,是字符串常量"MY LovE"的首地址,那么strs就是字符串常量"MY LovE"的首地址。strs是常量的地址,那么他就是不可以修改的。
最后我们重新来理解一下下面两种定义的区别
char strs[] = "MY LovE";
char *pstrs = strs;
char *pstrs = "MY LovE";
两种定义的方式,我们所定义的结果都是相同的,唯一不同的是,他们一个是变量 一个是常量,而常量是不可以被修改的。
扩展
如果上面的指针是整型指针,数组也是整型数组会怎么样呢?
答案是 首先:指针数组不能这样定义:
char *pints = {1, 2, 3, 4};//错误的
其次,C语言中常量可分为4种:
- 数值常量(如整型浮点型等)
-
- 字符常量(普通字符、转义字符)
-
- 字符串常量(“ewfae fserg”)
-
- 符号常量(定义的常量)
所以它只能先定义整型数组变量 进行赋值,再定义指针,最后将数组的首地址赋值给指针。
最后
以上就是轻松微笑为你收集整理的关于C语言中 字符串 指针 和字符数组的理解字符串常量和字符数组指针为什么???最后我们重新来理解一下下面两种定义的区别扩展的全部内容,希望文章能够帮你解决关于C语言中 字符串 指针 和字符数组的理解字符串常量和字符数组指针为什么???最后我们重新来理解一下下面两种定义的区别扩展所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复