c语言 字符型数据与字符串c语言常量的定义差别;简述char ch[]={‘a’,‘b’,‘c’};与char ch{}=“abc”;差别

3284人阅读
J2EE(17)
综述:在C语言中字符串或字符数组最后都会有一个额外的字符‘\0’来表示结束,而在java语言中没有结束符这一概念。具体见下面分析。
  在C语言中字符串和字符数组基本上没有区别,都需要结束符;如:char s[4]={'a','b','c','d'};此字符数组的定义编译可以通过,但却没有关闭数组,若其后需要申请内存,那么以后的数据均会放入其中,尽管它的长度不够,但若为 char s[5]={'a','b','c','d'};则系统会自动在字符串的最后存放一个结束符,并关闭数组,说明字符数组是有结束符的;
& & 而字符串定义的长度必须大于字符序列的长度,如:char s1[4]={&abcd&};编译不能通过,而应写成char s1[5]={&abcd&};并且系统会自动在字符串的最后存放一个结束符,说明字符串有结束符;
在C语言中使用strlen()函数可以测数组的长度,strlen(()函数计算的时候不包含结束符'\0'。
char s[5]={'a','b','c','d'};
char s1[5]={&abcd&};
int a=strlen(s);
int b=strlen(s1);
结果是a,b均为4;
注:printf函数跟strlen一样,打印输出字符串/数组时都以'\0'作为结束符,即:打印输出到'\0'为止(不包括'\0')。
2.Java语言
  字符串和字符串数组都是不需要结束符的;
  如:char[] value={'j','a','v','a','语','言'};
& & & & String s1=new String(value);
& & & & String s2=&java语言&;  
   int a=value.length;
& & & & int b=s1.length();
& & & & int c=s2.length();
  运行得到的结果a,b,c都是6,说明字符串和字符串数组都不需要结束符。但注意此处value.length和s1.length(),在数组中有属性length可以记录数组对象的长度,而length()方法是File类中的一个实例方法,用于返回文件的大小,当然也可以返回字符串的大小。
3.java中无需结束符的原因
Java里面一切都是对象,是对象的话,字符串肯定就有长度,即然有长度,编译器就可以确定要输出的字符个数,当然也就没有必要去浪费那1字节的空间用以标明字符串的结束了。比如,数组对象里有一个属性length,就是数组的长度,String类里面有方法length()可以确定字符串的长度,因此对于输出函数来说,有直接的大小可以判断字符串的边界,编译器就没必要再去浪费一个空间标识字符串的结束。
4.java字符串末尾空字符的处理
java和c通信的时候,由于c中的char中有结束符的,所以当java收到C发来的字符串时,后面往往会有若干空字符,如果不做处理的话,java会对其一并输出,为了将空字符处理掉不输出,可以采用如下两种方法:
调用java字符串的trim()方法,该方法会将字符串前后的空字符读去掉。
方法二:自己实现去掉尾部空字符的方法:
* 截取掉C中之前的字符串。即只截取前的字符
* @param s:尾部带有空字符的java字符串
public static String deletTailChar0(String s){
if(s == null){
char[] chars = s.toCharArray();
StringBuffer sb = new StringBuffer();
for(char c : chars){
Character ch =
if(0 == ch.hashCode()){ //如果到了字符串结束,则跳出循环
sb.append(c);
return sb.toString();
1.Java&数组初始化的两种方法:& &
& & 静态初始化:&程序员在初始化数组时为数组每个元素赋值;
& &&动态初始化:&数组初始化时,程序员只指定数组的长度,由系统为每个元素赋初值。
public class ArrayInit {
public static void main(String[] args) {
//静态初始化数组:方法一
String cats[] = new String[] {
&Tom&,&Sam&,&Mimi&
//静态初始化数组:方法二
String dogs[] = {&Jimmy&,&Gougou&,&Doggy&};
//动态初始化数据
String books[] = new String[2];
books[0] = &Thinking in Java&;
books[1] = &Effective Java&;
System.out.println(cats.length);
System.out.println(dogs.length);
System.out.println(books.length);
}注意,声明一个数组不需分配任何存储空间,它仅仅是代表你试图创建一个数组。跟C/C++声明一个数组的明显区别就是空间的大小没有被特别标识。因此,下面的声明将会引起一个编译期错误。
int num[5];
即:上面代码Demo中静态初始化中的方法二,如果改为String&dogs[3]&=&{&Jimmy&,&Gougou&,&Doggy&}; &则在编译时报错。
一个数组的大小将在数组使用new关键字真正创建时被给定,例如:
int num[];
num = new int[5];
迭代器(Iterator)是按照一定的顺序对一个或多个容器中的元素从前往后遍历的一种机制,比如for循环就是一种最简单的迭代器,对一个数组的遍历也是一种的迭代遍历的过程。GOF给出的定义为:提供一种方法访问一个容器(container)对象中各个元素,而又不需暴露该对象的内部细节。
迭代器其实就是维护一个当前的指针,这个指针可以指向当前的元素,可以返回当前所指向的元素,可以移到下一个元素的位置,通过这个指针可以遍历容器的所有元素。迭代器一般至少会有以下几种方法:
First(); //将指针移至第一个位置或获得第一个元素
GetCurrent(); //获得当前所指向的元素
MoveNext(); //移至下一个元素
2.1 C++中的迭代器:
void TestIterator()
vector&int&
// 定义一容器
for(int i = 0; i & 5; i++)
vec.push_back(i*2);
//添加元素
//用迭代器访问容器中的每个元素
cout && &iterator vector:& &&
for(vector&int&::iterator itr = vec.begin(); itr != vec.end(); itr ++)
cout && *itr && &
&; //itr是一个指针,指向当前的元素, 所以要解引用获得元素值
map&int, string& //创建一个map,对应学号-姓名的键值对
//添加元素
student.insert(pair&int, string&(1, &张三&));
student.insert(pair&int, string&(3, &王五&));
student.insert(pair&int, string&(2, &李四&));
//遍历容器中的元素
cout && &iterator map:& &&
for (map&int, string&::iterator itr = student.begin(); itr != student.end(); itr ++)
cout && itr-&first && &--&& && itr-&second &&
c++中的容器(如vector、map、list、set等)一般会提供四个迭代器:
iterator:正向迭代,从前往后遍历,可修改元素的值
const_iterator:正向常量迭代,但不能修改元素的值,因为指向的是const的引用
reverse_iterator:反向迭代,从后往前遍历,可修改元素的值
const_reverse_iterator:反向常量迭代,但不能修改元素的值,因为指向的是const的引用
每一种迭代器都提供一对首尾位置的标志begin和end。
2.2 Java中的迭代器:
public static void testIterator() {
//创建一个列表
List&Integer& list = new ArrayList&Integer&();
list.add(4); //添加元素
list.add(3);
list.add(7);
//返回一个迭代器,并遍历列表中的元素
Iterator&Integer& iterator = list.iterator();
while (iterator.hasNext()) {
Integer value = iterator.next();
System.out.print(value + &
System.out.println();
//返回ListIterator迭代器并从后往前遍历列表的元素
ListIterator&Integer& listIterator = list.listIterator(list.size());
System.out.println(&ListIterator:&);
while (listIterator.hasPrevious()) {
Integer value = listIterator.previous();
System.out.print(value + &
System.out.println();
Java中的List接口及其实现类可以通过iterator()返回Iterator,或通过listIterator()和listIterator(int&index)&返回ListIterator。
Iterator和ListIterator都是迭代器,ListIterator继承自Iterator。Iterator只能对列表进行遍历,且只能从前往后遍历,ListIterator可以修改列表,且可以选择往前或往后遍历。
java中map容器的遍历(可分别利用keySet或entrySet):
方法一:keySet遍历key+value:
Iterator&String& iter = map.keySet().iterator();
while (iter.hasNext()) {
key = iter.next();
value = map.get(key);
方法二:entrySet遍历key+value:
Iterator&Entry&String, String&& iter = map.entrySet().iterator();
Entry&String, String&
while (iter.hasNext()) {
entry = iter.next();
key = entry.getKey();
value = entry.getValue();
迭代器小结:C++中通过容器对象的begin或end方法来获取到迭代器,其迭代器的含义是一个指针,指向容器中的元素;而java中的迭代器是一个对象,通过容器的iterator()方法得到容器的迭代器,之后通过迭代器对象的方法hasNext()来获取到容器的指向。
3.C语言常用字符串函数
函数名: strrchr&
功& 能: 在串中查找指定字符的最后一个出现&
用& 法: char *strrchr(char *str, char c);
char fullname=&./lib/lib1.so&;
ptr = strrchr(fullname,'/');
printf(&filename is %s&,++ptr);
//运行结果:filename is lib1.so
函数名: strchr&
功& 能: 在串中查找指定字符的第一个出现&
用& 法: char *strchr(char *str, char c);
char fullname=&./lib/lib1.so&;
ptr = strrchr(fullname,'.');
printf(&after strchr() is %s&,++ptr);
//运行结果:after strchr() is
/lib/lib1.so
函数名: strtok&
功& 能: 在串中查找指定字符的第一个出现&
用& 法: char *strtok(char *s, char *delim);
1.strtok函数的实质上的处理是,strtok在s中查找包含在delim中的字符并用NULL(’\0′)来替换,直到找遍整个字符串。这句话有两层含义:(1)每次调用strtok函数只能获得一个分割单位。(2)要获得所有的分割单元必须反复调用strtok函数。
2.strtok函数以后的调用时的需用NULL来替换s.
3.形参s(要分割的字符串)对应的变量应用char s[]=”….”形式,而不能用char *s=”….”形式。
char buf[]=”Golden Global View”;
char* token = strtok( buf, ” “);
while( token != NULL )
printf( ”%s “, token );
token = strtok( NULL, ” “);
/*其结果为:
strcspn() 用来计算字符串 str 中连续有几个字符都不属于字符串 accept,其原型为:
& & int strcspn(char *str, char *accept);
【参数说明】str、accept为要进行查找的两个字符串。
strcspn() 从字符串 str 的开头计算连续的字符,而这些字符都完全不在字符串 accept 中。简单地说,若 strcspn() 返回的数值为 n,则代表字符串 str 开头连续有 n 个字符都不含字符串 accept 中的字符。
【返回值】返回字符串 str 开头连续不含字符串 accept 内的字符数目。
注意:如果 str 中的字符都没有在 accept 中出现,那么将返回 atr 的长度;检索的字符是区分大小写的。
提示:函数
的含义与 strcspn() 相反,可以对比学习。
【示例】返回s1、s2包含的相同字符串的位置。&
#include&stdio.h&
#include &stdlib.h&
#include&string.h&
int main()
char* s1 = &http://c.biancheng.net/cpp/u/biaozhunku/&;
char* s2 = &c is good&;
int n = strcspn(s1,s2);
printf(&The first char both in s1 and s2 is :%c\n&,s1[n]);
printf(&The position in s1 is: %d\n&,n);
system(&pause&);
}运行结果:
The first char both in s1 and s2 is :c
The position in s1 is: 7再看一个例子,判断两个字符串的字符是否有重复的。
#include&stdio.h&
#include &stdlib.h&
#include&string.h&
int main()
char* s1 = &http://c.biancheng.net/cpp/xitong/&;
char* s2 = &z -+*&;
if(strlen(s1) == strcspn(s1,s2)){
printf(&s1 is diffrent from s2!\n&);
printf(&There is at least one same character in s1 and s2!\n&);
system(&pause&);
运行结果:
s1 is diffrent from s2!strpbrk()函数检索两个字符串中首个相同字符的位置,其原型为:
& & char *strpbrk( char *s1, char *s2);
【参数说明】s1、s2要检索的两个字符串。
strpbrk()从s1的第一个字符向后检索,直到'\0',如果当前字符存在于s2中,那么返回当前字符的地址,并停止检索。
【返回值】如果s1、s2含有相同的字符,那么返回指向s1中第一个相同字符的指针,否则返回NULL。
注意:strpbrk()不会对结束符'\0'进行检索。
【函数示例】输出第一个相同字符之后的内容。
#include&stdio.h&
#include&string.h&
int main(void){
char* s1 = &http://see./cpp/u/xitong/&;
char* s2 = &see&;
char* p = strpbrk(s1,s2);
printf(&The result is: %s\n&,p);
printf(&Sorry!\n&);
输出结果:
The result is: see./cpp/u/xitong/
C语言中常用的API函数可参考:
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:382821次
积分:4528
积分:4528
排名:第5139名
原创:86篇
转载:49篇
评论:39条
(1)(2)(2)(4)(1)(1)(3)(5)(1)(2)(2)(1)(2)(1)(1)(1)(2)(1)(2)(7)(1)(1)(4)(1)(1)(1)(2)(1)(4)(2)(3)(5)(2)(3)(5)(5)(1)(6)(6)(4)(2)(17)(11)(4)C语言常犯语法错误_尚学堂it吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0可签7级以上的吧50个
本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:14贴子:
C语言常犯语法错误
1 字符常量与字符串常量混淆。c=&a&;在这里就混淆了字符常量与字符串常量,字符常量是由一对单引号括起来的单个字符,字符串常量是一对双引号括起来的字符序列。2 忽略了“=”与“==”的区别在许多高级语言中,用“=”符号作为关系运算符“等于”。如在BASIC程序中可以写:if (a=3) then …但C语言中,“=”是赋值运算符,“==”是关系运算符。如:if (a==3) a=b;前者是进行比较,a是否和3相等,后者表示如果a和3相等,把b值赋给a。3 输入变量时忘记加地址运算符“&”int a,b;scanf(&%d%d&,a,b);这是不合法的。Scanf函数的作用是:按照a、b在内存的地址将a、b的值存进去。“&a”指a在内存中的地址。
贴吧热议榜
使用签名档&&
保存至快速回贴&&/&&&&/&&
字符型数据就是字符。
字符型数据的表示
字符型数据是用单引号括起来的一个字符。例如:
'a'、'b'、'='、'+'、'?'
都是合法字符型数据。
在C语言中,字符型数据有以下特点:
字符型数据只能用单引号括起来,不能用双引号或其它括号。
字符型数据只能是单个字符,不能是字符串。
字符可以是字符集中任意字符。但数字被定义为字符型之后就不能参与数值运算。如'5'和5 是不同的。'5'是字符型数据,不能参与运算。
转义字符是一种特殊的字符。转义字符以反斜线&\&开头,后跟一个或几个字符。转义字符具有特定的含义,不同于字符原有的意义,故称&转义&字符。例如,在前面各示例中printf函数的格式串中用到的&\n&就是一个转义字符,其意义是&回车换行&。转义字符主要用来表示那些用一般字符不便于表示的控制代码。
常用的转义字符及其含义
转义字符的意义
横向跳到下一制表位置
反斜线符&\&
1~3位八进制数所代表的字符
1~2位十六进制数所代表的字符
广义地讲,C语言字符集中的任何一个字符均可用转义字符来表示。表中的\ddd和\xhh正是为此而提出的。ddd和hh分别为八进制和十六进制的ASCII代码。如\101表示字母&A& ,\102表示字母&B&,\134表示反斜线,\XOA表示换行等。
【例3-8】转义字符的使用。
#include&stdio.h&
int main(void){
int a,b,c;
a=5; b=6; c=7;
printf(& ab c\tde\rf\n&);
printf(&hijk\tL\bM\n&);
字符变量的类型说明符是char。字符变量类型定义的格式和书写规则都与整型变量相同。例如:
字符变量在内存中的存储形式及使用方法
每个字符变量被分配一个字节的内存空间,因此只能存放一个字符。字符值是以ASCII码的形式存放在变量的内存单元之中的。
如x的十进制ASCII码是120,y的十进制ASCII码是121。对字符变量a、b赋予'x'和'y'值:
a='x';
b='y';
实际上是在a、b两个单元内存放120和121的二进制代码:
所以也可以把它们看成是整型量。C语言允许对整型变量赋以字符值,也允许对字符变量赋以整型值。在输出时,允许把字符变量按整型量输出,也允许把整型量按字符量输出。
整型量为二字节量,字符量为单字节量,当整型量按字符型量处理时,只有低八位字节参与处理。
【例3-9】向字符变量赋以整数。
#include&stdio.h&
int main(void){
printf(&%c,%c\n&,a,b);
printf(&%d,%d\n&,a,b);
本程序中定义a,b为字符型,但在赋值语句中赋以整型值。从结果看,a,b值的输出形式取决于printf函数格式串中的格式符,当格式符为&c&时,对应输出的变量值为字符,当格式符为&d&时,对应输出的变量值为整数。
【例3-10】
#include&stdio.h&
int main(void){
a='a';
b='b';
printf(&%c,%c\n%d,%d\n&,a,b,a,b);
本例中,a,b被说明为字符变量并赋予字符值,C语言允许字符变量参与数值运算,即用字符的ASCII 码参与运算。由于大小写字母的ASCII 码相差32,因此运算后把小写字母换成大写字母。然后分别以整型和字符型输出。
字符串是由一对双引号括起的字符序列。例如: &CHINA& , &C program& , &$12.5& 等都是合法的字符串。字符串和字符不同,它们之间主要有以下区别:
字符由单引号括起来,字符串由双引号括起来。
字符只能是单个字符,字符串则可以含一个或多个字符。
可以把一个字符型数据赋予一个字符变量,但不能把一个字符串赋予一个字符变量。在C语言中没有相应的字符串变量,也就是说不存在这样的关键字,将一个变量声明为字符串。但是可以用一个字符数组来存放一个字符串,这将在一章内予以介绍。
字符占一个字节的内存空间。字符串占的内存字节数等于字符串中字节数加1。增加的一个字节中存放字符&\0& (ASCII码为0)。这是字符串结束的标志。
例如,字符串 &C program& 在内存中所占的字节为:
字符'a'和字符串&a&虽然都只有一个字符,但在内存中的情况是不同的。
'a'在内存中占一个字节,可表示为:
&a&在内存中占二个字节,可表示为:
推荐文章 TOP10

我要回帖

更多关于 c语言整型常量 的文章

 

随机推荐