在对Java有了一定的适应之后,我现在正在尝试扩大我的视野并尝试C编程。但是,即使访问了多个视频和网站,我似乎也无法理解 C 中的指针。
下面的代码应该从用户那里获取两个字符串,获取两个字符串的长度,然后将长度相互比较。然后,程序应通过指针返回两个名称中最长的一个(非常小心地返回换行符之前的长度,而不是变量的分配大小)。因此,当用户输入"Peterson"(name1)和"Thisisareallylonglastname"(name2)时,程序应通过指针/name2连接返回"Thisisareallylonglastname"。
我遇到的问题是,当尝试运行代码(使用 MinGW 编译器在 Eclipse Neon C/C++ IDE 中编写)时,我在控制台中没有得到任何输出。我相当确定我已经在窗口中正确设置了 MinGW 安装的路径,但为了确保我还手动将环境添加到项目中。在我对指针的困惑和通常是一个蹩脚的编码员之间,我不确定我的程序(无疑是新手)错误是什么。我在霓虹灯 IDE 中没有收到任何类型的错误。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
/* Two variables that take family names' input from the user with a maximum length of 256 */
char name1[256];
char name2[256];
char *ch = NULL;
printf("When two people marry there can sometimes be a debate which last/family name will henceforth be used (as a hyphenated last name is not always feasible.");
printf("A simple way to avoid squabbles is to simply take the longest family name of the two (soon-to-be) partners.");
printf("This program will take your name inputs and compare their length against one another; it will then return the longest name to be put on the document.");
printf("Enter your last name for 1 :");
gets(name1);
printf("Enter your last name for 2 :");
gets(name2);
int size1 = strlen(name1);
printf("Length of name 1:");
printf(size1);
int size2 = strlen(name2);
printf("Length of name 2:");
printf(size2);
if (size1 > size2)
{
ch = &name1;
}
else
{
ch = &name2;
}
if(!ch)
{
printf("The largest family name found is:");
printf(*ch);
}
return(0);
}
一个主要问题是你的最终输出是在条件if (!ch)
下 - 在英语中,它读作"如果指针ch
是null
值"。 由于它指向两个(非null
)内存位置之一,因此此检查将永远不会通过。
如果您将其更改为if (ch)
(或者只是省略检查,因为我们知道它不是null
)并修复其他人在评论中指出的printf
问题,我认为您会得到更好的结果。
指向 char 的指针和 char 数组都是在 C 中表示字符串的方式,因此是相同的类型。主要区别在于,对于数组,内存是在编译时分配的,而对于指针,您可以为其分配一个数组(就像您尝试的那样)或动态分配内存。
所以当你在做
ch = &name1;
您实际正在做的是尝试将指向字符串 name1 的指针分配给 ch,该指针的类型不同,应该会引发错误。相反,你真的想做
ch = name1;
相反,*ch 与 ch[0] 相同 - 您正在访问字符串的第一个字符,因此要打印出来,您需要
printf("%s",ch);
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
/* Two variables that take family names' input from the user with a maximum length of 256 */
char name1[256];
char name2[256];
char *ch = NULL;
printf("When two people marry there can sometimes be a debate which last/family name will henceforth be used (as a hyphenated last name is not always feasible.");
printf("A simple way to avoid squabbles is to simply take the longest family name of the two (soon-to-be) partners.");
printf("This program will take your name inputs and compare their length against one another; it will then return the longest name to be put on the document.");
printf("Enter your last name for 1 :");
gets(name1);
printf("Enter your last name for 2 :");
gets(name2);
int size1 = strlen(name1);
printf("Length of name 1: %d", size1);
int size2 = strlen(name2);
printf("Length of name 2: %d", size2);
if (size1 > size2)
{
ch = name1;
}
else
{
ch = name2;
}
printf("The largest family name found is: %s", ch);
return(0);
}
这应该可以解决问题。您还应该使用scanf("%s", str)
而不是 get。
当你这样做时char name1[256]
name1 被"视为指针",所以你必须做ch = name1
而不是ch = &name1
,因为 ch 和 name1 都是指针。
当你这样做时:
if(!ch)
{
printf...
}
您只会在 ch 为 null 时才打印,而您不希望打印,因为在这种情况下,您希望打印 ch 是否有值,因此您应该执行以下操作:
if(ch)
{
printf...
}
同样在 C 中,printf 必须接收有关您尝试打印的变量的信息,请检查 printf 示例以了解它
主要问题是你期望printf
像System.out.println
一样充当多态函数,但它没有。printf
的原型是
int printf( const char * restrict format, ... );
第一个参数始终是字符串;该字符串可能包含转换说明符,这些说明符控制任何其他参数的格式设置方式。
所以与其写:
printf("Length of name 1:");
printf(size1);
你会写:
printf( "Length of name 1: %dn", size1 );
或
printf( "Length of name 1: " );
printf( "%dn", size1 );
格式字符串中的%d
告诉printf
相应的参数应具有int
类型,并且您希望将其值显示为十进制数字字符串。 有关转换说明符的完整列表,请参阅在线 C 2011 标准第 7.21.6.1 节。
printf
不会像System.out.println
那样自动将换行符附加到所有输出 - 您必须在格式字符串 (n
) 中指定它。
标准输出通常是行缓冲的- 输出不会显示在控制台上,直到 a) 缓冲区已满,b) 缓冲区手动刷新fflush
,c) 缓冲区中出现换行符,或 d) 输入函数(fgets
、scanf
等)紧跟在输出函数之后。
C 和 Java 中的数组语义截然不同。在 C 中,数组不是引用对象 - 它们不指向堆上动态分配的内存。 但是,数组下标运算a[i]
是根据指针算术 -*(a + i)
定义的。 在 C 中发生的情况是,当数组表达式不是sizeof
或一&
元运算符的操作数,或者不是用于初始化声明中的数组的字符串文本时,表达式将从类型"T
的 N 元素数组"转换为"指向T
的指针",并且表达式的值是数组第一个元素的地址。
这是一种非常冗长的说法,而不是写作
ch = &name1;
你应该写
ch = name1;
相反。表达式name1
"衰减"到指向数组第一个元素的指针,表达式的结果类型为char *
。 表达式&name1
的类型是char (*)[256]
(指向 256 元素数组的char
),这不是您想要的。 它们都将评估到相同的位置(模化任何类型转换),但类型很重要。
最后。。。
从不 从不从不 从不 使用gets
.它将在您的代码中引入故障点/主要安全漏洞。 它在 C99 标准发布后不久就被弃用,并在 C2011 中正式从标准库中删除。 几十年来,这个图书馆功能造成了无数的混乱。 不要使用它,即使在玩具代码中也不要使用。 它是C编程语言的"汉兰达II"——它从未存在过。 请改用fgets
。