问题描述
你好;
我的程序有问题,需要计算一个IP地址的@host网络。程序的步骤是:
- 在二进制(int)中的“网络”变量中添加掩码和ip
- 将“reseau”变量转换为十进制(在 char[] 中)
- 返回 main 中的“network”变量
无论如何,我在第 1 步。为了看到一切正常,我试图返回包含二进制加法的字符串“reseau”。
从返回类型为 'char' 的函数中返回 'char *' 使得 没有强制转换的整数 [-Wint-conversion] 33. return reseau;
我怀疑这是因为您无法返回这样的字符选项卡(根据我的研究),但我无法弄清楚。
代码:
#include <stdio.h>
#include <stdio.h>
#include <string.h>
char calcul(char* octet,char* masque);
void main(){
char octetB[]="11000000101010000000000100000111";
char masqueB[]="11111111111111111111111100000000";
printf("octetB : %s\n",octetB);
printf("octetB 3e valeur : %c\n",octetB[2]);
printf("Adresse réseau : %s\n",calcul(octetB,masqueB));
}
char calcul(char* octet,char* masque){
int i;
char reseau[100];
printf("\n");
printf("octet dans calcul : %s\n",octet);
printf("masque dans calcul : %s\n",masque);
for(i=0; i<32; i++){
if((octet[i]='1') && (masque[i]='1')){
reseau[i]='1';
} else {
reseau[i]='0';
}
printf("nombre %d : %d\n",i,reseau[i]);
}
return reseau;
}
所以我很想得到一些帮助来知道我哪里出错了? 为了理解。谢谢:D
解决方法
使用 malloc()
的解决方案的缺点是分配了内存,但释放该内存的责任不明确。调用者甚至不需要知道内存是动态分配的(为什么要这样做?),并且无法释放它会导致内存泄漏。通常,释放分配的责任应该是明确的。在这种情况下,这不是一个好的解决方案。
一个简单(但仍然不完美)的解决方案是静态分配返回的字符串:
const char* calcul( const char* octet,const char* masque )
{
static char reseau[33] = "" ;
...
return reseau;
}
但这存在不可重入的问题(多线程或递归代码中的问题),调用者仍然需要了解与使用静态缓冲区相关的限制和问题。返回的指针对于所有调用者都是相同的,因此如果随后调用该函数,则该字符串将被修改。调用者可以复制字符串,或确保它在再次调用函数之前已完成对它的所有处理。动态内存分配可能更好,但仍然需要调用者了解内部内存管理才能正确使用它。
该解决方案的另一个缺点是返回 const
不能在函数外部执行写访问,因此如果有必要,调用者必须将字符串复制到本地缓冲区。返回非常量将是一个非常糟糕的主意 - 您将修改函数内的“隐藏”缓冲区。
更常见和更灵活的习惯用法是调用者“拥有”缓冲区并将其传递给函数以进行填充。这样内存可以是一个数组,也可以根据调用者的需要动态分配。在这种情况下,您还将传递数组的长度,以便函数可以避免溢出调用者的缓冲区:
const char* calcul( const char* octet,const char* masque,char* reseau,size_t reseau_len )
{
...
for( i = 0;
octet[i] != 0 && masque[i] != 0 && i < reseau_len;
i++)
{
...
}
return reseau;
}
那么这个函数可能会被这样调用:
char reseau_buf[sizeof(octetB)] ;
printf( "Adresse réseau : %s\n",calcul( octetB,masqueB,reseau_buf,sizeof(reseau_buf) ) ) ;
请注意,最后一个版本也没有对 masque
或 octet
的长度做任何假设——循环在所有输入中较短的一个处停止。如果它们不同,这是调用方的错误,函数实现将“优雅地”且确定性地失败,因此更容易调试。
除了对作业的解释
以上似乎都没有正确解决您似乎误解的任务。我希望解决方案看起来像:
#include <stdio.h>
#include <stdint.h>
uint32_t subnet( uint32_t ip,uint32_t mask,char* subnet_str ) ;
int main()
{
uint32_t ip = 0xC0A80001 ; // 192.168.0.1
uint32_t netmask = 0xFFFFFF00 ; // 255.255.255.0
char ipstring[] = "000.000.000.000" ;
printf( "0x%08X : ",subnet(ip,netmask,ipstring) ) ;
printf( "%s\n",ipstring ) ;
}
uint32_t subnet( uint32_t ip,char* subnet_str )
{
// Step 1 : apply mask to get subnet
uint32_t network = ...
// Step to: convert network to "xxx.xxx.xxx.xxx" string form
// in subnet_str
...
// Step 3
return network ;
}
有输出:
0xC0A80000 : 192.168.1.0
对任何问题的明确帮助都需要一个新问题。但是比您已经投入的工作要简单得多。第 1 步和第 2 步都可以用一行代码实现。
,问题是您的函数 calcul()
返回一个字符数组或指向字符 (char*
) 的指针,尽管您的函数定义说返回类型是 char
。这就是您收到编译错误的原因。
此外,您不能返回数组 reseau
。此变量是本地变量,仅在您的函数中可用。在函数 calcul()
之外,此字符数组不再有效。
您的代码中的下一个问题是 reseau
最后没有空终止。因此,您的 printf()
不会按预期工作。
最后我在你的代码中发现了另一个问题。语句 octet[i]='1'
是一个赋值语句。在您的情况下,您需要进行比较。您必须将其更改为 octet[i]=='1'
(带有双等号)。
向上:
我已经考虑了您的意见和解释。现在它可以工作了(使用 malloc 系统)。
感谢您的评论。
这里是更新后的代码,供遇到该主题的人使用:
char* calcul(char* octet,char* masque){
int i;
char reseau[100];
printf("\n");
printf("octet dans calcul : %s\n",octet);
printf("masque dans calcul : %s\n",masque);
for(i=0; i<32; i++){
if((octet[i]=='1') && (masque[i]=='1')){
reseau[i]='1';
} else {
reseau[i]='0';
}
printf("nombre %d : %d\n",i,reseau[i]);
}
char* result = malloc(strlen(reseau)+1);
strcpy(result,reseau);
return result;
}
,
您的代码无法编译,因为您在 char
函数处返回 calcul()
并返回一个字符数组。如果你想返回 reseau
字符数组,你可以使用指针来完成。看看下面的代码和你的代码的区别,看看如何实现它。
您的代码中也存在一些逻辑问题,例如 reseau
数组中没有结束行,这会导致在您想要的字符串之后打印垃圾值。并且您在代码中使用一个相等的 =
代替双相等的 ==
来比较相等。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
const char* calcul(char* octet,char* masque);
int main(){
char octetB[]="11000000101010000000000100000111";
char masqueB[]="11111111111111111111111100000000";
printf("octetB : %s\n",octetB);
printf("octetB 3e valeur : %c\n",octetB[2]);
printf("Adresse réseau : %s\n",calcul(octetB,masqueB));
}
const char* calcul(char* octet,char* masque){
int i;
char *reseau = malloc(100);
printf("\n");
printf("octet dans calcul : %s\n",masque);
for(i=0; i<32; i++){
if((octet[i]=='1') && (masque[i]=='1')){//use double equal to compare
reseau[i]='1';
} else {
reseau[i]='0';
}
printf("nombre %d : %c\n",reseau[i]);
}
reseau[i]= '\0';//add endline
return reseau;
}