c - 创建数组的动态声明

标签 c arrays variables dynamic declaration

我想让make array wich动态地声明,我想像这样。我想让make程序识别单词中的字符。

char i;
scanf("%c",&i);
char word[]=i;
printf("%c",word[0]);


我也尝试过这样的事情

char i;
scanf(%c,&i);
char *word=i;
printf("%c",word[0]);


我不知道如何使它工作

最佳答案

让我们从基础开始。在写时要声明的内容:

char word[]=i;


是一个字符数组,将根据=符号右边的内容进行初始化。在这种情况下,i是单个字符(即使从技术上说,它是无效的初始化程序)。因此,实质上,您正在尝试声明大小为1的字符数组。

如果允许的话,word不会是一个字符串,因为它不是(也不能是)null-terminated。它只是char类型的数组,不能用作字符串。 (请注意char word[]="i";将起作用-并以null终止)

当您将word声明为:

char *word=i;


您创建了一个指向char类型的指针,该指针未正确初始化以保存i的内存地址。

(指针只是包含内存中存储的其他内容的地址作为其值,在这种情况下,您已将该地址设置为i的值,该值可能在系统保留的内存范围内,并且可能会导致立即分段故障。

您可能想要的是:

char *word=&i;


i的地址存储为word的值的位置。尽管这将为您提供指向i的字符指针,但与动态分配无关,仅涉及指针。

为了正确地动态分配word,您仍然需要创建一个名为word的指针,但是您需要分配一个word指向的内存块。 (指向该内存块的起始地址)。因此,要为word动态分配空间,您将希望看到类似以下内容的内容:

char *word = NULL;            /* initialization to NULL is good practice */
word = malloc (numbytes * sizeof *word); /* allocate numbytes of storage */


然后,您有了一个指针word,其值是大小为(numbytes x sizeof *word)字节的新内存块的起始地址。 (由于sizeof *word只是sizeof (char),其值为1)。因此,您创建了一个大小为numbytes的内存块。

您对该内存块负有两个责任(1)您必须保留一个指向该内存块起始地址的指针;因此(2)当不再需要内存时,您可以free。 (1)表示您的代码中没有word++;, etc..。如果您需要迭代一个指针值,请创建一个指针,例如:

char *p = word;


然后,可以在p上使用指针算法,而不会影响word的值。

然后,您可以按照自己喜欢的任何方式填充单词,只要在最后留出一个空终止符的空间(如果您打算将其用作字符串),并且不要尝试写超过numbytes的数据对它。

因此,在您的情况下,如果要动态分配word来容纳要打印为字符串的字符i,则可以轻松地执行以下操作:

char *word = NULL;

word = malloc (10 * sizeof *word);
if (!word) {  /* always validate each allocation */
    fprintf (stderr, "error: virtual memory exhausted.\n");
    return 1;
}

if (scanf ("9%s", word))
    printf ("word contains '%s'\n", word);

free (word);


注意:使用scanf ("9%s", word)时,遇到第一个空格时将立即停止阅读。您可能想使用scanf ("9%[^\n]%*c", word),它实际上表示%9[^\n]最多读取9个字符(不包含\n),然后%*c读取并丢弃换行符而不将其添加到。所以你的测试:

if (scanf ("9%s", word))


确保scanf已将至少一个字符作为字符串(空终止词)读入scanf,成功读取后,该字符将添加到word的匹配计数中,从而构成scanf。然后,match count = 1返回匹配计数,以确保仅在成功读取后才进行打印。

另请注意:通过在格式字符串中包含宽度说明符scanf(或scanf),将读取的字符9的数量限制为%9s。这样可确保您不能写超出分配给word的内存末尾,同时保证有可用于以空值终止字符串的空间。

另一个尼特。如果您希望用户输入数据,则提示用户输入数据,这样就不会让用户看着屏幕上闪烁的光标,不知道程序是否挂起,等等。在一个简短的例子中。

#include <stdio.h>
#include <stdlib.h>

int main (void) {

    char *word = NULL;

    word = malloc (10 * sizeof *word);
    if (!word) {  /* always validate each allocation */
        fprintf (stderr, "error: virtual memory exhausted.\n");
        return 1;
    }

    printf ("\nEnter up to 9 characters to store in 'word': ");
    if (scanf ("%9[^\n]%*c", word))
        printf ("word contains '%s'\n", word);

    free (word);

    return 0;
}


使用/输出

$ ./bin/dynalloc

Enter up to 9 characters to store in 'word': dog
word contains 'dog'

$ ./bin/dynalloc

Enter up to 9 characters to store in 'word': 1234567890
word contains '123456789'

$ ./bin/dynalloc

Enter up to 9 characters to store in 'word': my dog
word contains 'my dog'


如果您有任何问题,请告诉我。

关于c - 创建数组的动态声明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33377875/

相关文章:

c - 如何用C语言的结构体数组实现插入排序?

javascript - 根据元素的数字顺序合并两个数组

当参数名和变量名相等时,c++类 setter 设置不同的变量

javascript - 如何在imageLoaded回调函数中使用变量?

通过指针改变结构体内容

c++ - VirtualAllocEx 成功返回一个基地址,但是 WriteProcess 失败,错误是 487

c - C中的浮点除法

php - 返回 PHP 数组名

ruby-on-rails - 使用 Ruby 检索作为散列值的数组元素

php - 使用参数在 PHP 中调用 cgi/py