为什么更新一个变量也会更新分配给它的变量?
Why is updating one variable also updating the variable assigned to it?
我从用户那里得到一个字符串并将其存储在一个变量 plaintext
中,然后我想在 for 循环中将该字符串转换为小写并将其存储在一个单独的变量中 plaintextLowercase
.但是,当我将 plaintextLowercase
变量中的字符更改为小写时,plaintext
变量中也会发生同样的情况,我希望保持不变。我的代码如下。
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <ctype.h>
int main(void)
{
// get_string() is a function defined in the header file cs50.h that prompts the user for string input and returns that string input
string plaintext = get_string("plaintext: ");
string plaintextLowercase = plaintext;
//this converts the entire string to lowercase, but the issue is it is doing the same to the 'plaintext' variable as well
//I only want the 'plaintextLowercase' string to be lowercase, while the 'plaintext' variable
for (int i = 0, n = strlen(plaintext); i < n; i++)
{
plaintextLowercase[i] = tolower(plaintextLowercase[i]);
}
printf("%s\n", plaintext);
printf("%s\n", plaintextLowercase);
}
您使用的库混淆了无用的 typedef
和宏背后的基本 C 概念。如果您在 C 中使用字符串,那么 char *
是唯一正确的方法。避免使用其他东西,特别是如果您仍在学习该语言的工作原理。如果你的 book/library/course 建议你使用像 CS50 的 string
这样的不透明数据类型,那么就把它扔掉,去找别的东西去研究。
这里发生的事情是您的 cs50.h
header 将 string
定义为:
typedef char * string;
因此,您错误地给人的印象是:
string a = "123";
string b = a;
将以某种方式神奇地创建字符串的副本。事实并非如此,因为代码等同于:
char *a = "123";
char *b = a;
a
和 b
都是指针,并且最终会 指向 内存中相同的常量字符串文字。没有复制发生。
这与 get_string()
函数的结果相同,该函数在后台为您动态分配一个带有 malloc()
的字符串。所以这段代码:
string plaintext = get_string("plaintext: ");
string plaintextLowercase = plaintext;
有同样的“问题”。您的 lowercase
和 plaintextLowercase
只是指向同一内存区域的两个指针,包含相同的字符串。如果要复制字符串,可以使用strdup()
:
string plaintext = get_string("plaintext: ");
string plaintextLowercase = strdup(plaintext);
当然,由于新字符串也是动态分配的,所以当您不再需要它时,请不要忘记free()
它:
free(plaintextLowercase);
由 get_string()
分配的字符串在退出时由库自动为您解除分配(另一个 counter-intuitive CS50 东西)。
我从用户那里得到一个字符串并将其存储在一个变量 plaintext
中,然后我想在 for 循环中将该字符串转换为小写并将其存储在一个单独的变量中 plaintextLowercase
.但是,当我将 plaintextLowercase
变量中的字符更改为小写时,plaintext
变量中也会发生同样的情况,我希望保持不变。我的代码如下。
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <ctype.h>
int main(void)
{
// get_string() is a function defined in the header file cs50.h that prompts the user for string input and returns that string input
string plaintext = get_string("plaintext: ");
string plaintextLowercase = plaintext;
//this converts the entire string to lowercase, but the issue is it is doing the same to the 'plaintext' variable as well
//I only want the 'plaintextLowercase' string to be lowercase, while the 'plaintext' variable
for (int i = 0, n = strlen(plaintext); i < n; i++)
{
plaintextLowercase[i] = tolower(plaintextLowercase[i]);
}
printf("%s\n", plaintext);
printf("%s\n", plaintextLowercase);
}
您使用的库混淆了无用的 typedef
和宏背后的基本 C 概念。如果您在 C 中使用字符串,那么 char *
是唯一正确的方法。避免使用其他东西,特别是如果您仍在学习该语言的工作原理。如果你的 book/library/course 建议你使用像 CS50 的 string
这样的不透明数据类型,那么就把它扔掉,去找别的东西去研究。
这里发生的事情是您的 cs50.h
header 将 string
定义为:
typedef char * string;
因此,您错误地给人的印象是:
string a = "123";
string b = a;
将以某种方式神奇地创建字符串的副本。事实并非如此,因为代码等同于:
char *a = "123";
char *b = a;
a
和 b
都是指针,并且最终会 指向 内存中相同的常量字符串文字。没有复制发生。
这与 get_string()
函数的结果相同,该函数在后台为您动态分配一个带有 malloc()
的字符串。所以这段代码:
string plaintext = get_string("plaintext: ");
string plaintextLowercase = plaintext;
有同样的“问题”。您的 lowercase
和 plaintextLowercase
只是指向同一内存区域的两个指针,包含相同的字符串。如果要复制字符串,可以使用strdup()
:
string plaintext = get_string("plaintext: ");
string plaintextLowercase = strdup(plaintext);
当然,由于新字符串也是动态分配的,所以当您不再需要它时,请不要忘记free()
它:
free(plaintextLowercase);
由 get_string()
分配的字符串在退出时由库自动为您解除分配(另一个 counter-intuitive CS50 东西)。