OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5049|回复: 12

c语言问题

[复制链接]

33

主题

87

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
230
金钱
230
注册时间
2017-1-2
在线时间
31 小时
发表于 2017-4-8 11:16:49 | 显示全部楼层 |阅读模式
1金钱
我在vc6.0上编了一段话,如下
#include <stdio.h>
#include <string.h>
char* cipsend_updata(int id,int longs);
int main()
{
        char* ATCIPSEND=cipsend_updata(1,10);
        printf("ATCIPSEND=%s",ATCIPSEND);
       
}
char* cipsend_updata(int id,int longs)
{         
        char cipsend[16]="AT+CIPSEND=0,00";
        cipsend[11]=id+0x30;
        if(longs<10)
                cipsend[14]=longs+0x30;
        else
        {
                cipsend[13]=longs/10+0x30;
                cipsend[14]=longs-(longs/10)*10+0x30;
        }
        printf("%s",cipsend);
        return cipsend;
}


输出结果是:
AT+CIPSEND=1,10AT+CIPSEND=
也就是说在cipsend_updata功能里面的打印,打印出来了。但是主函数里的ATCIPSEND并没有被赋值,就是说cipsend_updata的返回值没有返回出来。为什么会这样?
ATCIPSEND=cipsend_updata(1,10);这句话有问题

最佳答案

查看完整内容[请看2#楼]

这是找来的链接 http://blog.csdn.net/sinat_27706697/article/details/47856491 2. 字符串常量 [objc] view plain copy 01.charchar *str2 = "good"; 02.while (*str2 != '\0') { 03. putchar(*str2++); 04.} 注意: "good"本身就是一个常量内容,它存放在只读存储区,并且有自己的地址,而变量str2中存放的内容就是常量 "good"所在的地址。所以上述str2++操作完全是正确的。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

33

主题

87

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
230
金钱
230
注册时间
2017-1-2
在线时间
31 小时
 楼主| 发表于 2017-4-8 11:16:50 | 显示全部楼层
这是找来的链接
http://blog.csdn.net/sinat_27706697/article/details/47856491
2. 字符串常量




[objc] view plain copy
01.charchar *str2 = "good";  
02.while (*str2 != '\0') {  
03.    putchar(*str2++);  
04.}  


注意: "good"本身就是一个常量内容,它存放在只读存储区,并且有自己的地址,而变量str2中存放的内容就是常量 "good"所在的地址。所以上述str2++操作完全是正确的。
回复

使用道具 举报

33

主题

1628

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6679
金钱
6679
注册时间
2015-8-25
在线时间
1036 小时
发表于 2017-4-8 11:46:42 | 显示全部楼层
本帖最后由 szczyb1314 于 2017-4-8 11:47 编辑

cipsend是在子函数中定义的数组,即一个地址(指针)。当子函数返回的时候这个指针被释放了,不会返回值的。定义成全局变量即可
回复

使用道具 举报

33

主题

87

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
230
金钱
230
注册时间
2017-1-2
在线时间
31 小时
 楼主| 发表于 2017-4-8 15:04:07 | 显示全部楼层
szczyb1314 发表于 2017-4-8 11:46
cipsend是在子函数中定义的数组,即一个地址(指针)。当子函数返回的时候这个指针被释放了,不会返回值的 ...

为什么我定义成数组就会被释放?
如果在int形函数里定义一个int变量,再把这个变量作为返回值返回,就有返回值
同样定义一个指针,返回指针,也能获得返回值
你明白吗

给你看看正点原子里esp8266资料里的一个函数
u8* atk_8266_check_cmd(u8 *str)
{
       
        char *strx=0;
        if(USART3_RX_STA&0X8000)                //接收到一次数据了
        {
                USART3_RX_BUF[USART3_RX_STA&0X7FFF]=0;//添加结束符
                strx=strstr((const char*)USART3_RX_BUF,(const char*)str);
        }
        return (u8*)strx;
}
回复

使用道具 举报

33

主题

1628

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6679
金钱
6679
注册时间
2015-8-25
在线时间
1036 小时
发表于 2017-4-8 15:22:18 | 显示全部楼层
本帖最后由 szczyb1314 于 2017-4-8 15:38 编辑
firing00 发表于 2017-4-8 15:04
为什么我定义成数组就会被释放?
如果在int形函数里定义一个int变量,再把这个变量作为返回值返回,就有 ...

你把你的数组换成指针也行,数组就是不行。
数组是个局部变量,用完就释放了他的存储空间。
比如:
char *func(void)
{      char str[]="hello";
      //other operation
     return str;
}
void main()
{
      printf("%s",func());
}
这个代码是打不出hello的
char *func(void)
{      char *str="hello";
      //other operation
     return str;
}
void main()
{
      printf("%s",func());
}

这个是可以打印hello的。
He who fights with monsters should look to it that he himself does not become a monster, when you gaze long into the abyss, the abyss also gazes into you.
过于执着就会陷入其中,迷失自己,困住自己。
回复

使用道具 举报

33

主题

1628

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6679
金钱
6679
注册时间
2015-8-25
在线时间
1036 小时
发表于 2017-4-8 15:59:12 | 显示全部楼层
#include <stdio.h>
char *func(char *s)
{
        char *str = "hello";
        printf("%c\r\n",*(str+1));
        printf("%s\r\n",s);
        return str;
}
void main()
{
    printf("%s\r\n",func("hell"));
}
输出结果是:
e
hell
hello


#include <stdio.h>
char *func(char *s)
{
        char str[] = "hello";
        printf("%c\r\n",str[1]));
        printf("%s\r\n",s);
        return str;
}
void main()
{
    printf("%s\r\n",func("hell"));
}
输出结果是:
e
hell
乱码


到底是啥意思你自己理解吧,我可能也理解的不是很清楚。C的水很深的。
He who fights with monsters should look to it that he himself does not become a monster, when you gaze long into the abyss, the abyss also gazes into you.
过于执着就会陷入其中,迷失自己,困住自己。
回复

使用道具 举报

7

主题

162

帖子

0

精华

高级会员

Rank: 4

积分
541
金钱
541
注册时间
2017-4-6
在线时间
67 小时
发表于 2017-4-8 18:18:45 | 显示全部楼层
这里涉及到了两个地方,1.C语言的内存管理 ;2.数组与指针的赋值方式。

1.定义局部变量时,MCU会分配一块固定的地址空间给这个变量,这个区域叫做“栈”,在使用完之后,“栈”中的数据会被刷新掉,
至于为什么会被刷新,就涉及到了调用函数的操作。这一点2L说的是对的。

2.数组在定义时,其地址是固定的,你做的是往固定地址里面填充数据,return 返回的是数组的地址
指针在定义时,变量的值为地址。你做的是把一个地址赋给了指针变量,return 返回的是字符串的地址,而不是指针本身的地址。
你可以进行这样一个尝试,赋值给指针的时候,使用*p = data;然后再返回p,看看结果是什么
回复

使用道具 举报

6

主题

110

帖子

0

精华

高级会员

Rank: 4

积分
553
金钱
553
注册时间
2014-10-23
在线时间
195 小时
发表于 2017-4-8 23:43:10 | 显示全部楼层
JUSTNIUB 发表于 2017-4-8 18:18
这里涉及到了两个地方,1.C语言的内存管理 ;2.数组与指针的赋值方式。

1.定义局部变量时,MCU会分配一 ...

很透彻,涨知识了。
回复

使用道具 举报

33

主题

87

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
230
金钱
230
注册时间
2017-1-2
在线时间
31 小时
 楼主| 发表于 2017-4-9 10:50:06 | 显示全部楼层
我把测试的语句和运行结果贴出来

#include <stdio.h>
#include <string.h>
char* array();
char* pointer();
char* pointerdata();
void main()
{
        printf("1:array():%s\n",array());
        printf("2:pointer():%s\n",pointer());
        printf("3:pointerdata():%s\n",pointerdata());

}
char* array()
{
        char arr[5]="abcd";
        printf("1:arr=%s\n",arr);
        return arr;
}
char* pointer()
{
        char* poi="abcd";
        printf("2:poi=%s\n",poi);
        return poi;
}
char* pointerdata()
{
        char data[5]="abcd";
        char* poi_dat=data;
        printf("3:poi_dat=%s\n",poi_dat);
        return poi_dat;
}


cmd.png
回复

使用道具 举报

33

主题

87

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
230
金钱
230
注册时间
2017-1-2
在线时间
31 小时
 楼主| 发表于 2017-4-9 11:10:56 | 显示全部楼层
第1个、函数里定义的变量用完会被释放,所以主函数再把这个变量地址里的内容打印出来,已经没有了,释放了;
第2个、我想起我记忆中的一个知识点了,但是想不起来在哪里看的了,如果有错请纠正。
对于char* poi="abcd";这种语句是要把字符串"abcd"的地址赋值给poi指针,但是你又没有真的定义一个字符串,这个地址是谁呢。是这样的它会自动从内存中存在的去寻找这个字符,第一个就是a,第二个b。。。然后连起来把这个地址给poi。所以"abcd"没有被释放,因为它本来就在固定的内存表里。;
第3个、当然是data被释放了,再按照这个地址去找时,发现被释放了;
回复

使用道具 举报

33

主题

87

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
230
金钱
230
注册时间
2017-1-2
在线时间
31 小时
 楼主| 发表于 2017-4-9 11:11:26 | 显示全部楼层
JUSTNIUB 发表于 2017-4-8 18:18
这里涉及到了两个地方,1.C语言的内存管理 ;2.数组与指针的赋值方式。

1.定义局部变量时,MCU会分配一 ...

看下面我的理解
回复

使用道具 举报

33

主题

1628

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6679
金钱
6679
注册时间
2015-8-25
在线时间
1036 小时
发表于 2017-4-9 11:52:17 | 显示全部楼层
firing00 发表于 2017-4-9 11:27
这是找来的链接
http://blog.csdn.net/sinat_27706697/article/details/47856491
2. 字符串常量

对,就是这个。字符串是常量,字符数组是变量
He who fights with monsters should look to it that he himself does not become a monster, when you gaze long into the abyss, the abyss also gazes into you.
过于执着就会陷入其中,迷失自己,困住自己。
回复

使用道具 举报

7

主题

162

帖子

0

精华

高级会员

Rank: 4

积分
541
金钱
541
注册时间
2017-4-6
在线时间
67 小时
发表于 2017-4-10 14:02:41 | 显示全部楼层
firing00 发表于 2017-4-9 11:11
看下面我的理解

昨天没上, 没看到。
你的理解是正确的,有一点忘记说了,字符串是常量,常量的地址是不会改变的,在C语言的内存管理中,它存放在数据段中。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-8-22 07:09

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表