鱼C论坛

 找回密码
 立即注册
查看: 1649|回复: 5

[已解决]一些基础性的问题

[复制链接]
发表于 2023-3-24 22:10:35 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
#include<stdio.h>

#include<string.h>
int main(){
        char s1[50];
        int smalls1,smalls2;//定义了两个整型变量
        char hello[] = "hello world";

        smalls1 = "hello";//将字符串赋值给了整型变量
        smalls2 = " world";//将字符串赋值给了整型变量

        sprintf(s1,"%s%s",smalls1,smalls2);//本意是要练习这个库函数,效果是把两个字符串拼接起来,写进s1

        printf("%s\n",s1);//这里输出了hello world

        printf("%d\n",strcmp(hello,s1));这里输出了0

        printf("%s\n",smalls1);//这里输出了hello
        
return 0;
} 


上述代码犯了很低级的错误,奇怪的是编译器只是警告了
[Warning] assignment makes integer from pointer without a cast

用strcmp()比较“hello world”和本应出错的s1时返回值是0,表示二者一致,请问编译器是怎么处理把字符串赋值给int型变量这种情况的?
自动帮我纠错了?
最佳答案
2023-3-25 15:57:13
在这段代码中,将字符串赋值给整型变量 smalls1 和 smalls2 是犯了低级错误,应该把它们声明为字符数组,而不是整型变量。编译器发出了警告,但并没有阻止程序继续运行。

在执行 sprintf(s1,"%s%s",smalls1,smalls2); 时,由于 smalls1 和 smalls2 是整型变量,而不是字符串,因此编译器会将它们解释为指针,即将它们的地址作为字符串的起始地址。这样会导致程序访问未定义的内存区域,可能导致程序崩溃或输出错误的结果。

在这个特定的例子中,由于 smalls1 和 smalls2 的地址正好是字符串 "hello" 和 " world" 的起始地址,因此 sprintf 函数实际上拼接了这两个字符串,并将结果写入了字符数组 s1 中。但这种行为是不可预测的,因为它依赖于内存布局的细节。

在比较 "hello world" 和 s1 时,由于它们的内容相同,strcmp 函数返回了 0。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-3-24 23:39:50 | 显示全部楼层
调试代码琢磨吧。
#include<stdio.h>

#include<string.h>
int main(){
        char s1[50];
        int smalls1,smalls2;//定义了两个整型变量
        char hello[] = "hello world";

                char str1[] = "hello";
                char str2[] = " world";


                printf("%p\n", smalls1);
                printf("%p\n", smalls2);

                printf("\n");


                printf("%p\n", str1);
                printf("%p\n", str2);

        smalls1 = str1;
        smalls2 = str2;

                printf("%p\n", smalls1);
                printf("%p\n", smalls2);

        
return 0;
} 


int strcmp(const char *s1,const char *s2);
当s1<s2时,返回为负数;
当s1=s2时,返回值= 0;
当s1>s2时,返回正数

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-3-25 03:03:26 | 显示全部楼层
字符串赋值给int型变量,其实并没有什么太大的问题。
在这里,字符串可以拆分为一个个的字符,其分别对应着ASCII码,相当于将这些数值传进去给S1。
又因为strcmp函数,就是用来逐个字符转换为ASCII码来比较的,所以也可以比较成功。
最后,因为你选择的是%s,所以输出自然又由ASCII码转换为字符串。
个人愚见:类型只是容器,吃饭喝水都可用碗,只是杯子更适合喝水。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-3-25 08:21:40 | 显示全部楼层
指针也是数值
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-3-25 10:37:19 | 显示全部楼层
在这段代码中,将字符串赋值给整型变量是不合法的操作。编译器可能会将字符串的地址强制转换为整数值,这样可能会导致意想不到的结果。

在这个例子中,编译器可能会将字符串的地址转换为一个整数值,并将其赋给整型变量。由于字符串的地址通常是一个比较大的值,因此将其转换为整数值可能会导致截断或损失精度。因此,将字符串赋值给整型变量是不安全的。

在这个例子中,使用sprintf()函数将两个字符串连接起来,这是正确的做法。该函数将两个字符串连接成一个新的字符串,并将其写入目标缓冲区。在这个例子中,目标缓冲区是s1数组。使用sprintf()函数可以避免将字符串赋值给整型变量的问题。

对于警告信息“assignment makes integer from pointer without a cast”,它是编译器对于类型不匹配的一种警告,可能是因为在代码中出现了将指针类型转换为整型类型的情况。在这种情况下,编译器会将指针的值转换为一个整数值,并将其赋给整型变量。如果这个警告被忽略了,那么可能会导致程序运行出错。

对于strcmp()函数返回值为0的问题,这是因为sprintf()函数正确地将两个字符串连接在一起,并将结果存储在s1数组中。因此,s1数组中存储的字符串与"hello world"相同,导致strcmp()函数返回0。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-3-25 15:57:13 | 显示全部楼层    本楼为最佳答案   
在这段代码中,将字符串赋值给整型变量 smalls1 和 smalls2 是犯了低级错误,应该把它们声明为字符数组,而不是整型变量。编译器发出了警告,但并没有阻止程序继续运行。

在执行 sprintf(s1,"%s%s",smalls1,smalls2); 时,由于 smalls1 和 smalls2 是整型变量,而不是字符串,因此编译器会将它们解释为指针,即将它们的地址作为字符串的起始地址。这样会导致程序访问未定义的内存区域,可能导致程序崩溃或输出错误的结果。

在这个特定的例子中,由于 smalls1 和 smalls2 的地址正好是字符串 "hello" 和 " world" 的起始地址,因此 sprintf 函数实际上拼接了这两个字符串,并将结果写入了字符数组 s1 中。但这种行为是不可预测的,因为它依赖于内存布局的细节。

在比较 "hello world" 和 s1 时,由于它们的内容相同,strcmp 函数返回了 0。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-10-7 17:26

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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