首页 > 编程知识 正文

c语言怎么判断常量合不合法,字符串常量和字符串的区别

时间:2023-05-03 15:29:48 阅读:120000 作者:2785

c语言中字符串常量到底存在于哪里?

常量存储总结

局部变量、静态局部变量、全局变量、全局静态变量、字符串常量和动态请求的内存空间

1、局部变量存储在堆栈中

2、全局变量、静态变量(全局和局部静态变量)存储在静态存储中

3、new申请的内存在堆里

4、字符串常数也存储在静态存储区

补充说明:

1、栈中的变量内存随定义区间的结束自动释放; 对于堆,必须手动自由。 否则,它会一直存在到程序结束。

2 .对于静态存储,其中的变量常数在程序运行过程中一直存在,不释放。 另外,变量常数其中只有一个副本,不会出现相同变量和常数的不同副本。

=====================================

以下文章清楚地介绍了字符串常量:

char *c='zhouming ';

在书中,字符串“zhouming”被视为常量,并位于此程序的内存静态区域中。

c是字符型指针,对于局部变量,它存储在堆栈中,而指针变量包含地址。

此地址是字符串中第一个字符z的地址。

使用printf (输出时,如果在格式化时选择%s,则输出zhouming。 这意味着当printf遇到终结符“”时将停止打印。

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

其一般int i=1;

所有字符文字都位于静态内存区域中

因为几乎不需要更改字符串常数,所以配置在静态内存区域可以提高效率

示例:

char str1[]='abcd ';

char str2[]='abcd ';

const char str3[]='abcd ';

const char str4[]='abcd ';

常数char * str5=' ABCD ';

常数char * str6=' ABCD ';

char *str7='abcd ';

char *str8='abcd ';

cout(str1==str2) endl;

cout(str3==str4) endl;

cout(str5==str6) endl;

cout(str7==str8) endl;

结果是0 0 1 1

str1、str2、str3、str4是阵列变量,具有各自的存储器区域; 字符数组作为局部变量存储在堆栈区域中

另一方面,str5、str6、str7、str8是指针,指向相同的常数区域。“abcd”保存在静态数据区域,是全局的。

问题部署:

看看下面程序的输出:

#include stdio.h

char *returnStr ()

{

char *p='hello world!' ;

返回p;

}

int main () )

{

char *str=NULL; //请务必初始化,习惯

str=returnStr (;

printf(%s(n )、str );

返回0;

}

这没有任何问题。 ' hello world!' 是存储在静态数据区域中的字符串常量。

将存储该字符串常数的静态数据区域的起始地址分配给指针,

因而,在returnStr函数结束时,不回收该字符串常数所在的存储器,因此能够通过指针顺利地访问。

但是,存在以下问题。

#include stdio.h

char *returnStr ()

{

char p[]='hello world!' ;

返回p;

}

int main () )

{

char *str=NULL; //请务必初始化,习惯

str=returnStr (;

printf(%s(n )、str );

返回0;

}

'赫尔洛世界! "存储在静态数据区域中的字符串常数。 是的。

但是,字符串常量被分配给存储在堆栈中的局部变量(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("%sn", str);

return 0;
}
 

这个问题可以通过下面的一个例子来更好的说明:

#include <stdio.h>
//返回的是局部变量的地址,该地址位于动态数据区,栈里

char *s1()
{
char* p1 = "qqq";//为了测试‘char p[]="Hello world!"’中的字符串在静态存储区是否也有一份拷贝
char p[]="Hello world!";
char* p2 = "w";//为了测试‘char p[]="Hello world!"’中的字符串在静态存储区是否也有一份拷贝
printf("in s1 p=%pn", p);
printf("in s1 p1=%pn", p1);
printf("in s1: string's address: %pn", &("Hello world!"));
printf("in s1 p2=%pn", p2);
return p;
}

//返回的是字符串常量的地址,该地址位于静态数据区

char *s2()
{
char *q="Hello world!";
printf("in s2 q=%pn", q);
printf("in s2: string's address: %pn", &("Hello world!"));
return q;
}

//返回的是静态局部变量的地址,该地址位于静态数据区

char *s3()
{
static char r[]="Hello world!";
printf("in s3 r=%pn", r);
printf("in s3: string's address: %pn", &("Hello world!"));
return r;
}

int main()
{
char *t1, *t2, *t3;
t1=s1();
t2=s2();
t3=s3();

printf("in main:");
printf("p=%p, q=%p, r=%pn", t1, t2, t3);

printf("%sn", t1);
printf("%sn", t2);
printf("%sn", t3);

return 0;
}

 
运行输出结果:

in s1 p=0013FF0C
in s1 p1=00431084
in s1: string's address: 00431074
in s1 p2=00431070
in s2 q=00431074
in s2: string's address: 00431074
in s3 r=00434DC0
in s3: string's address: 00431074
in main:p=0013FF0C, q=00431074, r=00434DC0
$
Hello world!
Hello world!
 

这个结果正好应证了上面解释,同时,还可是得出一个结论:
字符串常量,之所以称之为常量,因为它可一看作是一个没有命名的字符串且为常量,存放在静态数据区。
这里说的静态数据区,是相对于堆、栈等动态数据区而言的。
静态数据区存放的是全局变量和静态变量,从这一点上来说,字符串常量又可以称之为一个无名的静态变量,
因为"Hello world!"这个字符串在函数 s1和s2 中都引用了,但在内存中却只有一份拷贝,这与静态变量性质相当神似。

 

另外还有个实验:

 

 

[cpp]
#include <stdio.h>  
#include <stdlib.h>  
#include <math.h>  
int main()
{
 
    char *b;
 
    char *c;
 
    char a[]="chenhuijie";
    b="chenhuijie";
    c="chenhuijie";
    printf("%d,%d,%d,%dn",b,a,c,&("chenhuijie"));
 
 
 
 
 
}

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{

 char *b;

 char *c;

 char a[]="chenhuijie";
 b="chenhuijie";
 c="chenhuijie";
    printf("%d,%d,%d,%dn",b,a,c,&("chenhuijie"));

 

 

}

 

实验结果为:

4282272,1244988,4282272,4282272
请按任意键继续. . .

 

对了,字符常量‘a’

sizeof(‘a’)

为4,及一个字长。

 


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


typedef struct _http_str
{
        char *p;
        int   len;
        //for internal use only, field MUST be of integer type
        int   trait; //won't enlarge struct due to gcc's default alignment
} http_str_t;

int aa;

http_str_t * get_info()
{
        static http_str_t s = { "", 0, 0 };
        int a;
        char b[] = "abc";

        printf("s.p:%p, string addr:%pn", s.p, &(""));

        printf("b:%p, string addr:%pn", b, &("abc"));

        s.p = b;
        printf("s:%p, s->p:%p, a:%p, aa:%p, b:%pn", &s, s.p, &a, &aa, b);

        return &s;
}

int main()
{
        http_str_t *s =  get_info();

        printf("p=%pn", s->p);
        printf("*p=%sn", (s->p));

        printf("sizeof('a'):%lu, %lu, sizeof(5):%lu, sizeof(&"a"):%lun", sizeof('a'), sizeof("a"), sizeof(5), sizeof(&("a")));

        return 0;

}

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。