关于 C 中的指针和 strcpy()
About pointers and strcpy() in C
我正在练习使用 malloc()
和指针分配内存,但是关于指针的 1 个观察是,为什么 strcpy()
可以接受 str
变量而没有 *
:
char *str;
str = (char *) malloc(15);
strcpy(str, "Hello");
printf("String = %s, Address = %u\n", str, str);
但是对于整数,我们需要 * 给 str 一个值。
int *str;
str = (int *) malloc(15);
*str = 10;
printf("Int = %d, Address = %u\n", *str, str);
我真的很困惑为什么strcpy()
接受str
,因为在我自己的理解中,"Hello"
会被传递到str
的内存位置,这会导致一些错误。
*
称为间接或解引用运算符。
在你的第二个代码中,
*str = 10;
将 值 10 分配给 str
指向的内存地址。这是一个值(即单个变量)。
OTOTH,strcpy()
一次复制整个字符串。它接受两个 char *
参数,因此您不需要 *
在传递参数时取消引用以获取值。
您可以使用取消引用运算符,无需 strcpy()
,逐个元素复制,如
char *str;
str = (char *) malloc(15); //success check TODO
int len = strlen("Hello"); //need string.h header
for (i = 0; i < len; i ++)
*(str+i)= "Hello"[i]; // the * form. as you wanted
str[i] = 0; //null termination
许多字符串操作函数,包括 strcpy
,按照约定和设计,接受指向数组第一个字符的指针,而不是指向整个数组的指针,即使它们的 值 相同。
这是因为他们的类型不同;例如指向 char[10]
的指针与指向 char[15]
的指针具有不同的类型,因此将指针传递到整个数组是不可能的或非常笨拙的,除非您将它们到处投射或使不同长度的不同功能。
出于这个原因,他们建立了一个约定,即传递带有指向其第一个字符的指针的字符串,而不是整个数组,必要时可能带有它的长度。许多对数组进行操作的函数,例如 memset
,工作方式相同。
在 C 中,字符串(根据定义)是一个字符数组。然而(无论我们是否一直意识到这一点)我们几乎总是以使用指针访问数组而告终。因此,尽管 C 没有真正的 "string" 类型,但出于大多数实际目的,指向字符的指针类型(即 char *
)可用于此目的。几乎所有接受或 returns 字符串的函数实际上都会使用 char *
。这就是 strlen()
和 strcpy()
接受 char *
的原因。这就是 printf %s
期望 char *
的原因。在所有这些情况下,这些函数需要的是指向字符串第一个字符的指针。 (然后他们依次读取字符串的其余部分,在找到终止字符 '[=17=]'
时停止。)
在这些情况下,您不使用明确的 *
字符。 *
将只提取指向的字符(即字符串的第一个字符),但您不想提取第一个字符,您想要将整个字符串(即指向的指针)整个字符串)到 strcpy
这样它就可以完成它的工作。
在您的第二个示例中,您根本没有使用字符串。 (您使用了一个名为 str
的变量这一事实让我困惑了片刻。)您有一个指向某些整数的指针,并且您正在使用指向的第一个整数。由于您直接访问指向的内容之一,这就是为什么您确实需要明确的 *
字符。
嗯,这是第一个片段中发生的事情:
您首先动态分配 15 个字节的内存,将此地址存储到 char 指针,该指针指向一个 1 字节的数据序列(字符串)。
然后调用 strcpy()
,它遍历字符串并将字符逐字节复制到新分配的内存 space 中。每个字符都是基于 ASCII table 的数字,例如。字符 a = 97(看看 man ascii
)。
然后将此地址传递给 printf()
,它从字符串中逐字节读取,然后将其刷新到您的终端。
在第二个片段中,过程相同,您仍然分配 15 个字节,将地址存储在一个 int * 指针中。 int 是 4 字节数据类型。
当您执行 *str = 10
时,您正在取消引用指针以将值 10 存储在 str 指向的地址。提醒一下我前面写的,你可以做 *str = 'a',这个索引 0 整数的值将是 97,即使你试图将它作为一个 int 来读取。如果你愿意,你可以打印出来。
那么为什么strcpy()
可以接受一个int *
作为参数呢?因为它是一个可以写入的内存 space,一个字节一个字节。您可以将 "Hell" 存储在一个 int 中,然后将 "o!" 存储在下一个中。
一切都是为了使用方便。
看到 =
运算符和函数 strcpy
之间存在差异。
*
是顺从运算符。当你说 *str
时,它表示 str.
指向的内存位置的值
作为一个好习惯,使用这个
str = (char *) malloc( sizeof(char)*15 )
这是因为数据类型的大小在不同的平台上可能会有所不同。因此使用 sizeof
函数来确定其在 运行 时间的实际大小。
我正在练习使用 malloc()
和指针分配内存,但是关于指针的 1 个观察是,为什么 strcpy()
可以接受 str
变量而没有 *
:
char *str;
str = (char *) malloc(15);
strcpy(str, "Hello");
printf("String = %s, Address = %u\n", str, str);
但是对于整数,我们需要 * 给 str 一个值。
int *str;
str = (int *) malloc(15);
*str = 10;
printf("Int = %d, Address = %u\n", *str, str);
我真的很困惑为什么strcpy()
接受str
,因为在我自己的理解中,"Hello"
会被传递到str
的内存位置,这会导致一些错误。
*
称为间接或解引用运算符。
在你的第二个代码中,
*str = 10;
将 值 10 分配给 str
指向的内存地址。这是一个值(即单个变量)。
OTOTH,strcpy()
一次复制整个字符串。它接受两个 char *
参数,因此您不需要 *
在传递参数时取消引用以获取值。
您可以使用取消引用运算符,无需 strcpy()
,逐个元素复制,如
char *str;
str = (char *) malloc(15); //success check TODO
int len = strlen("Hello"); //need string.h header
for (i = 0; i < len; i ++)
*(str+i)= "Hello"[i]; // the * form. as you wanted
str[i] = 0; //null termination
许多字符串操作函数,包括 strcpy
,按照约定和设计,接受指向数组第一个字符的指针,而不是指向整个数组的指针,即使它们的 值 相同。
这是因为他们的类型不同;例如指向 char[10]
的指针与指向 char[15]
的指针具有不同的类型,因此将指针传递到整个数组是不可能的或非常笨拙的,除非您将它们到处投射或使不同长度的不同功能。
出于这个原因,他们建立了一个约定,即传递带有指向其第一个字符的指针的字符串,而不是整个数组,必要时可能带有它的长度。许多对数组进行操作的函数,例如 memset
,工作方式相同。
在 C 中,字符串(根据定义)是一个字符数组。然而(无论我们是否一直意识到这一点)我们几乎总是以使用指针访问数组而告终。因此,尽管 C 没有真正的 "string" 类型,但出于大多数实际目的,指向字符的指针类型(即 char *
)可用于此目的。几乎所有接受或 returns 字符串的函数实际上都会使用 char *
。这就是 strlen()
和 strcpy()
接受 char *
的原因。这就是 printf %s
期望 char *
的原因。在所有这些情况下,这些函数需要的是指向字符串第一个字符的指针。 (然后他们依次读取字符串的其余部分,在找到终止字符 '[=17=]'
时停止。)
在这些情况下,您不使用明确的 *
字符。 *
将只提取指向的字符(即字符串的第一个字符),但您不想提取第一个字符,您想要将整个字符串(即指向的指针)整个字符串)到 strcpy
这样它就可以完成它的工作。
在您的第二个示例中,您根本没有使用字符串。 (您使用了一个名为 str
的变量这一事实让我困惑了片刻。)您有一个指向某些整数的指针,并且您正在使用指向的第一个整数。由于您直接访问指向的内容之一,这就是为什么您确实需要明确的 *
字符。
嗯,这是第一个片段中发生的事情:
您首先动态分配 15 个字节的内存,将此地址存储到 char 指针,该指针指向一个 1 字节的数据序列(字符串)。
然后调用 strcpy()
,它遍历字符串并将字符逐字节复制到新分配的内存 space 中。每个字符都是基于 ASCII table 的数字,例如。字符 a = 97(看看 man ascii
)。
然后将此地址传递给 printf()
,它从字符串中逐字节读取,然后将其刷新到您的终端。
在第二个片段中,过程相同,您仍然分配 15 个字节,将地址存储在一个 int * 指针中。 int 是 4 字节数据类型。
当您执行 *str = 10
时,您正在取消引用指针以将值 10 存储在 str 指向的地址。提醒一下我前面写的,你可以做 *str = 'a',这个索引 0 整数的值将是 97,即使你试图将它作为一个 int 来读取。如果你愿意,你可以打印出来。
那么为什么strcpy()
可以接受一个int *
作为参数呢?因为它是一个可以写入的内存 space,一个字节一个字节。您可以将 "Hell" 存储在一个 int 中,然后将 "o!" 存储在下一个中。
一切都是为了使用方便。
看到 =
运算符和函数 strcpy
之间存在差异。
*
是顺从运算符。当你说 *str
时,它表示 str.
作为一个好习惯,使用这个
str = (char *) malloc( sizeof(char)*15 )
这是因为数据类型的大小在不同的平台上可能会有所不同。因此使用 sizeof
函数来确定其在 运行 时间的实际大小。