c 语言题 -字符数组

1、字符串常量与字符数组变量区别

#include<stdio.h>

int main()
{
char buf1[10] = "hello";
char buf2[10] = "hello";
if (buf1 == buf2)
printf("equal");
else
printf("not equal");

}

结果:not equal   buf1,buf2是存放栈区不同变量;

#include<stdio.h>
#include<stdlib.h>
int main()
{
    char* szStringA = "Hello,world!";
    char* szStringB = "Hello,world!";
char a[] = "Hello,world!";
char b[] = "Hello,world!";//不是字符串常量,是数组变量
    if (a == b){
printf("a=b");
} else{
printf("no");
}
if (szStringA = szStringB){
printf("A=B");
}else{
printf("A no");
}  
    return 0;
}

结果:no A=B;   szStringA,szStringB是字符常量的指针,都指向 "Hello,world!",存的是 "Hello,world!"的首地址;

常量存储总结
局部变量、静态局部变量、全局变量、全局静态变量、字符串常量以及动态申请的内存区

1、局部变量存储在栈中
2、全局变量、静态变量(全局和局部静态变量)存储在静态存储区
3、new申请的内存是在堆中
4、字符串常量也是存储在静态存储区

补充说明:
1、栈中的变量内存会随着定义所在区间的结束自动释放;而对于堆,需要手动free,否则它就一直存在,直到程序结束;
2、对于静态存储区,其中的变量常量在程序运行期间会一直存在,不会释放,且变量常量在其中只有一份拷贝,不会出现相同的变量和常量的不同拷贝。

关于字符串常量,下面有篇文章解释的很清晰:

char *c="zhouming";
书上说: "zhouming"这个字符串被当作常量而且被放置在此程序的内存静态区。
c为一个字符型指针,若为局部变量,则存储在栈内,该指针变量里面存了个地址,

该地址为字符串中第一个字母Z的地址。

 

当使用printf()输出时,格式化时选择%s,会输出zhouming,这是printf遇到结尾符号‘\0’即停止显示打印。

 

字符串“zhouming”是个常量,存储在一片连续的内存中,末尾有结尾符表示字符串的结束。

 

那一般的int i=1;


所有的字符窜常量都被放在静态内存区
因为字符串常量很少需要修改,放在静态内存区会提高效率

问题的引入:
看看下面的程序的输出:

#include <stdio.h>
char *returnStr()
{
char *p="hello world!";
return p;
}
int main()
{
char *str=NULL;//一定要初始化,好习惯
str=returnStr();
printf("%s\n", str);

return 0;
}
 

这个没有任何问题,因为"hello world!"是一个字符串常量,存放在静态数据区
把该字符串常量存放的静态数据区的首地址赋值给了指针,
所以returnStr函数退出时,该该字符串常量所在内存不会被回收,故能够通过指针顺利无误的访问。

但是,下面的就有问题:
#include <stdio.h>
char *returnStr()
{
char p[]="hello world!";
return p;
}
int main()
{
char *str=NULL;//一定要初始化,好习惯
str=returnStr();
printf("%s\n", str);

return 0;
}

 
"hello world!"是一个字符串常量,存放在静态数据区,没错,
但是把一个字符串常量赋值给了一个局部变量(char []型数组),该局部变量存放在栈中,
这样就有两块内容一样的内存,也就是说“char p[]="hello world!";”这条语句让“hello world!”这个字符串在内存中有两份拷贝,一份在动态分配的栈中,另一份在静态存储区。这是与前者最本质的区别,
当returnStr函数退出时,栈要清空,局部变量的内存也被清空了,
所以这时的函数返回的是一个已被释放的内存地址,所以打印出来的是乱码。

如果函数的返回值非要是一个局部变量的地址,那么该局部变量一定要申明为static类型。如下:

static 主要是为了限定范围用的。


#include <stdio.h>
char *returnStr()
{
static char p[]="hello world!";
return p;
}
int main()
{
char *str=NULL;
str=returnStr();
printf("%s\n", str);

return 0;
}

2、共同体


#include<stdio.h>
int main()
{
union   _UnionTest
{
unsigned int    i;
unsigned char   ch[2];
};
_UnionTest uniontest;
uniontest.i = 0x1420;
printf("%d\t%d\n", uniontest.ch[0], uniontest.ch[1]);

}

结果:32   20

3、字符数组 赋值与字符串赋值区别     ‘\0’,前者没有,后者有

 #include <iostream>
using namespace std;

int main(void)
{
char x[8] = {0};//赋值为8个0
//int ch = 123;
char y[8] = {0};
strncpy(x,"hello",sizeof(x));  x="hello"
strncpy(y,"hello world",sizeof(y));   目标字符串大于个数,截取8个放到数组中,,没有添加‘\0’,strlen找不到结束位置;
    cout<<strlen(x)<<" "<<strlen(y)<<endl;  
    cout<<x<<" "<<y<<endl;
    return 0;
}
5 13(乱码)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值