字符数组和字符指针

举报
ReCclay 发表于 2022/02/22 01:33:31 2022/02/22
【摘要】 I char sa[]="Hello World!" char *sp ="Hello World!"12 总的来说: char sa[]="Hello World!" //sa是个数组,sa也是...

I

char sa[]="Hello World!"
char *sp ="Hello World!"
  
 
  • 1
  • 2

总的来说:

char sa[]="Hello World!"

//sa是个数组,sa也是一个常量指针,不能改变sa的指向,”Hello World”是数组的初始化列表,可以通过下标或者间接操作来改变值

char *sp ="Hello World!"

//sp指向字符串常量,sp是一个变量指针,可以改变sp的指向。不能通过下标或者间接操作来改变值。如果硬要改变的话是编译通过但运行出错


1、字符数组中的元素可以改变,而指针所指字符串常量的元素不可以被改变。

sa[0]='h'; //合法
sp[0]='h'; //非法
  
 
  • 1
  • 2

只能这样(重新改变指向)

sp = "hello world"
  
 
  • 1

2、数组名sa是常量,其指向不可改变,而sp是变量,可以指向其他字符串。

sa = "Hello"; //非法
sp = "Hello"; //合法
  
 
  • 1
  • 2

对字符数组的赋值,要么在初始化的时候,要么就得用strcpy()

strcpy(sa, "Wang");
  
 
  • 1

3、字符指针必须赋值后引用。

因为声明的时候,并不分配内存


II

还有一个知识点,就是我们知道字符数组自动在后面添加结束符‘\0’,那

么真的是

什么时候都会进行添加吗?。。。。

然而并不是!!!

1、 char str[]=”12345”; 或者 char str[]={“12345”};
这种方法定义时,系统会自动在字符串的末尾加上字符串结束符,即 ‘\0’

2、char str[10]={‘1’,’2’,’3’,’4’,’5’};这种方法定义时,系统会自动从未初始化的元素开始,将之后的元素赋为\0,如上面的数组str中的元素实际上是:’1’,’2’,’3’,’4’,’5’,’\0’,’\0’,’\0’,’\0’,’\0’

但是!!!!
!!引用char str[]={‘1’,’2’,’3’,’4’,’5’};这种方法定义时,系统不会自动在字符串的末尾加上字符串结束符;

说明分立的并且未指定大小的字符数组是不会进行添0的!


通过一段代码进行理解。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main()

{

       char str1[]="12345";
       char str2[10]={'1','2','3','4','5'};
       char *str3="12345";
       char str4[]={'1','2','3','4','5',0};
       char str5[]={'1','2','3','4','5'};

       printf("%d,%d,%d,%d,%d,%d\n",str2[5],str2[6],str2[7],str2[8],str2[9],str3[4]);
       printf("各个字符串为:%s,%s,%s,%s,%s\n",str1,str2,str3,str4,str5);
       printf("各个字符串的所占的内存大小为:%d,%d,%d,%d,%d\n",sizeof(str1),sizeof(str2),sizeof(str3),sizeof(str4),sizeof(str5));
       printf("各个字符串的有效长度为:%d,%d,%d,%d,%d\n",strlen(str1),strlen(str2),strlen(str3),strlen(str4),strlen(str5));
       printf("%d\n",strcmp(str1,str3));
       printf("%d\n",strcmp(str1,str5));

}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

sizeof和strlen的知识补习:
http://blog.csdn.net/21aspnet/article/details/1539951

0,0,0,0,0,53 //注意这里的53是对应的ascii
各个字符串为:12345,12345,12345,12345,1234512345
各个字符串的所占的内存大小为:6,10,4,6,5
各个字符串的有效长度为:5,5,5,5,10
0
-1

Process returned 0 (0x0)   execution time : 0.246 s
Press any key to continue.

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

III

参考http://www.cnblogs.com/bugman/archive/2011/09/25/2190389.html博客,有所得:

1、lvalue required as increment operand (lvalue – 左值)

关于左值和右值得问题,不再专门开篇大论了!
概括来说:
左值 - -是可以进行存储数据的地方。
右值 - -是可以表示结果值。

这个是我自己以前写的一个程序

#include <stdio.h>
#include <stdlib.h>

int main()
{
    char len = 0;
    char str[] = "wang";
    char *p = str;

//    while(*str++ != '\0')str代表的是数组名,是不能进行++的
//    {
//        len++;
//    }
    while(*p++ != '\0')//用一个指针指向就可以了!
    {
        len++;
    }
    printf("%d", len);
    return 0;
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

当我使用注释那一段程序的时候,编译就有了lvalue required as increment operand 的error,百思不得其解。查资料方才了解到:数组名是常量指针,并不能像左值那样进行++操作!

(这也就引出了另一个知识点,指针常量和常量指针)

同时也了解到:数组名不是常量指针的情况只有两种,就是当数组名是sizeof和&的操作数时,前者产生整个数组的占用的字节数,后者产生一个指向数组的指针

2、下标引用和间接操作是一样的

 1 #include<stdio.h>
 2 int main(int argc,char **argv)
 3 {
 4     int array[]={1,2,3,4};
 5     int *b=array+1;
 6     printf("%d\n",b[1]);
 7     printf("%d\n",*(b+1));
 8     printf("%d\n",b[-1]);
 9     printf("%d\n",b[10]);
10     printf("%d\n",1[b]);
11     return 0;
12 }
  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

输出

3
3
1
32595
3
  
 
  • 1
  • 2
  • 3
  • 4
  • 5

这个例子说明了几个很有意思的事实,b是指针,但是b还是可以使用下标操作符,c在处理下标操作符时把b[1]看成*(b+1)
这也是为什么1[b]是合法的原因,1[b]被看成了*(1+b),在编译器看来b[1]和1[b]并没有区别。
并且c语言不进行下标检查,这是基于相信coder的设计思想,并且检查下标要消耗一定的资源

文章来源: recclay.blog.csdn.net,作者:ReCclay,版权归原作者所有,如需转载,请联系作者。

原文链接:recclay.blog.csdn.net/article/details/78034368

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。