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’,前者没有,后者有
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;
}