关于C中的指针和strcpy()

时间:2015-06-29 17:27:42

标签: c string pointers char strcpy

我正在使用带有指针的malloc()来练习分配内存,但有一个关于指针的观察是,为什么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的内存位置,这将导致一些错误。

5 个答案:

答案 0 :(得分:4)

在C中,字符串(根据定义)是一个字符数组。但是(无论我们是否一直都在意识到),我们几乎总是使用指针访问数组。因此,尽管C没有真正的“字符串”类型,但对于大多数实际用途,类型指针指向char(即char *)就是为此目的。几乎任何接受或返回字符串的函数都会使用char *。这就是strlen()strcpy()接受char *的原因。这就是printf %s期望char *的原因。在所有这些情况下,这些函数需要的是指向字符串第一个字符的指针。 (然后他们按顺序读取字符串的其余部分,当他们找到终止'\0'字符时停止。)

在这些情况下,您不使用明确的*字符。 *只会提取指向的字符(即字符串的第一个字符),但是你不想提取第一个字符,你想要提交整个字符串(即指向整个字符串)到strcpy所以它可以完成它的工作。

在你的第二个例子中,你根本没有使用字符串。 (你使用名为str的变量的事实让我困惑了一会儿。)你有一个指向一些int的指针,你正在使用指向的第一个int。由于您直接访问指向的内容之一,因此您需要明确的*字符。

答案 1 :(得分:1)

*称为间接或解除引用运算符。

在你的第二个代码中,

 *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

答案 2 :(得分:0)

按惯例和设计,许多字符串操作函数(包括strcpy)接受指向数组第一个字符的指针,而不是指向整个数组的指针,即使它们的是一样的。

这是因为他们的类型是不同的;例如指向char[10]的指针与指向char[15]的指针的类型不同,并且将指针传递给整个数组将是不可能或非常笨拙的,因为这样,除非你将它们转移到任何地方或制作不同长度的不同功能。

出于这个原因,他们建立了一个约定,即传递一个字符串,其指针指向其第一个字符,而不是整个数组,必要时可能还有它的长度。许多在数组上运行的函数(例如memset)的工作方式相同。

答案 3 :(得分:0)

嗯,这是第一个片段中发生的事情:

您首先动态分配15个字节的内存,将此地址存储到char指针,该指针是指向1字节数据序列(字符串)的指针。 然后调用strcpy(),它遍历字符串并将字符(每字节字节)复制到新分配的内存空间中。每个字符都是基于ASCII表的数字,例如。字符a = 97(看看man ascii)。

然后将此地址传递给printf(),该字符串从字符串读取,每字节字节数,然后将其刷新到终端。

在第二个片段中,进程是相同的,您仍然分配15个字节,将地址存储在int *指针中。 int是4字节数据类型。 执行*str = 10时,您将取消引用指针,将值10存储在str指向的地址处。提醒我之前写的内容,你可以做* str ='a',这个索引0整数的值是97,即使你试着把它读成int。如果愿意,你可以打印事件。

为什么strcpy()可以将int *作为参数?因为它是一个可以写入的内存空间,每字节字节数。你可以将“地狱”存储在一个int中,然后“o!”在下一个。

这就是使用简易性。

答案 4 :(得分:0)

请参阅=运算符与函数strcpy之间存在差异。

*是deference运算符。当你说*str时,它表示str指向的内存位置的值。

同样作为一种好习惯,请使用此

str = (char *) malloc( sizeof(char)*15 )

这是因为不同平台上数据类型的大小可能不同。因此,使用sizeof函数来确定其在运行时的实际大小。