- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
对于字符串,char *
或其他内容,我对C语言有很大的疑问。因此,在这种特殊情况下,我遇到了很大的问题。我想创建一个字符数组,但还不知道它将是多大。我想写这样的东西:
char test[];
char test[num_of_elements];
最佳答案
声明静态字符数组(字符串)
当您知道(或有一个合理的想法,需要将数组的大小)时,只需声明一个足够大的数组即可处理您的输入(即,如果名称不超过25个字符,则可以安全地声明name[26]
。字符串,您始终需要至少为,number of chars to store
, + 1
(对于以空字符结尾的字符)。
如果可能有几个字符超过25个,则声明数组长度比所需的字节数长就可以防止在数组末尾意外写入,这没什么不对。说name[32]
。
让我们在下面声明一个5-characters
数组,并查看信息如何存储在内存中。
char name[5] = {0}; /* always initialize your arrays */
5-contiguous bytes
数组供您使用。例如,您可以可视化初始化为零的5字节内存,如下所示:
+---+---+---+---+---+
name | 0 | 0 | 0 | 0 | 0 |
+---+---+---+---+---+
\
'name' holds the starting address for
the block of memory that is the array
(i.e. the address of the first element
like: 0x7fff050bf3d0)
name
保留“字符字符串”时,实际字符串不能超过
4 字符,因为您
必须以
结尾的字符串结尾为终止符为,即空字符'\0'
(或仅是数字0
,两者都是等效的)name
中,可以通过一次分配字符 来做到这一点:name[0] = 'J';
name[1] = 'o';
name[2] = 'h';
name[3] = 'n';
name[4] = 0; /* null-terminate. note: this was already done by initialization */
+---+---+---+---+---+
name | J | o | h | n | 0 | /* you actually have the ASCII value for */
+---+---+---+---+---+ /* each letter stored in the elements */
strcpy
,strncpy
,memcpy
,或者通过从文件流中读取信息,或者通过使用fgets
,getline
的文件描述符读取信息,或者使用简单的loop
和index variable
进行分配,或者使用一种字符串格式化功能,例如sprintf
等。例如,您可以使用以下任一方法完成相同的操作:/* direct copy */
strcpy (name, "John");
strncpy (name, "John", 5);
memcpy (name, "John", sizeof "John"); /* include copy of the terminating char */
/* read from stdin into name */
printf ("Please enter a name (4 char max): ");
scanf ("%[^\n]%*c", name);
strncpy
(最后一个将用作0
字符,然后使用null-terminating
,则需要手动终止,否则将字符串与strncpy (name, "John", 4);
一起终止)将没有有效的字符串(如果您在需要字符串的地方使用name[4] = 0;
,则将有一个不终止的char数组,这将导致undefined behavior
。)name
是什么,以及它与null-terminated string
的不同之处。认真地说,现在就停止学习吧,这是C语言的基础。(如果它不以array of characters
字符结尾-它不是c字符串。null-terminating
中声明。char *name = NULL; /* declare a pointer, and initialize to NULL */
name = malloc (5 * sizeof *name); /* allocate a 5-byte block of memory for name */
if (!name) { /* validate memory was allocated -- every time */
fputs ("error: name allocation failed, exiting.", stderr);
exit (EXIT_FAILURE);
}
/* Now use name, just as you would the statically declared name above */
strncpy (name, "John", 5);
printf (" name contains: %s\n", name);
free (name); /* free memory when no longer needed.
(if reusing name, set 'name = NULL;')
*/
stdlib.h
不会初始化它分配的内存的内容。如果要用零初始化新的内存块(就像我们对静态数组所做的那样),请使用malloc
而不是calloc
。您还可以使用malloc
,然后也调用malloc
。memset
。您可以使用realloc
重新分配由realloc
创建的原始内存块。 malloc
本质上会创建一个新的内存块,将内存从您的旧块复制到新的内存块,然后释放旧的内存块。由于旧的内存块已释放,因此您想使用临时指针进行重新分配。如果重新分配失败,您仍然可以使用原始的内存块。realloc
的任何调用中添加尽可能少的内存。通常看到的标准方案是从一些初始分配开始,然后在每次用尽时重新分配该数量的两倍。 (这意味着您需要跟踪当前分配了多少内存)。realloc
引用"
)。然后它将分配空间来容纳字符串,然后重新分配以将更多文本附加到原始字符串的末尾。最后,它将在退出之前释放所有正在使用的内存:#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (int argc, char **argv) {
if (argc < 2) { /* validate input */
fprintf (stderr, "error: insufficient input. usage: %s \"name\"\n",
argv[0]);
return 1;
}
size_t len = strlen (argv[1]); /* length of input */
size_t sz_mem = len + 1; /* memory required */
char *name = malloc (sz_mem * sizeof *name); /* allocate memory for name */
if (!name) { /* validate memory created successfully or throw error */
fputs ("error: name allocation failed, exiting.", stderr);
return 1;
}
printf ("\n allocated %zu bytes of memory for 'name'\n", sz_mem);
memset (name, 0, sz_mem); /* initialize memory to zero (optional) */
strncpy (name, argv[1], sz_mem); /* copy the null-terminator as well */
printf (" name: '%s' (begins at address: %p)\n", name, name);
/* realloc - make name twice as big */
void *tmp = realloc (name, 2 * sz_mem); /* use a temporary pointer */
if (!tmp) { /* check realloc succeeded */
fprintf (stderr, "error: virtual memory exhausted, realloc 'name'\n");
return 1;
}
memset (tmp + sz_mem, 0, sz_mem * sizeof *name); /* zero new memory */
name = tmp; /* assign new block to name */
sz_mem += sz_mem; /* update current allocation size */
printf (" reallocated 'name' to %zu bytes\n", sz_mem);
strncat (name, " reallocated", sizeof " reallocated");
printf ("\n final name : '%s'\n\n", name);
free (name);
return 0;
}
$ ./bin/arraybasics "John Q. Public"
allocated 15 bytes of memory for 'name'
name: 'John Q. Public' (begins at address: 0xf17010)
reallocated 'name' to 30 bytes
final name : 'John Q. Public reallocated'
"
之类的内存错误检查器来验证您的内存使用是否正确。 (没有任何借口,这样做很简单)只需键入valgrind
$ valgrind ./bin/arraybasics "John Q. Public"
==19613== Memcheck, a memory error detector
==19613== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==19613== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==19613== Command: ./bin/arraybasics John\ Q.\ Public
==19613==
allocated 15 bytes of memory for 'name'
name: 'John Q. Public' (begins at address: 0x51e0040)
reallocated 'name' to 30 bytes
final name : 'John Q. Public reallocated'
==19613==
==19613== HEAP SUMMARY:
==19613== in use at exit: 0 bytes in 0 blocks
==19613== total heap usage: 2 allocs, 2 frees, 45 bytes allocated
==19613==
==19613== All heap blocks were freed -- no leaks are possible
==19613==
==19613== For counts of detected and suppressed errors, rerun with: -v
==19613== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
==19613== HEAP SUMMARY:
==19613== in use at exit: 0 bytes in 0 blocks
==19613== total heap usage: 2 allocs, 2 frees, 45 bytes allocated
valgrind yourprogramexe
:==19613== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
关于c - char数组的内存分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32442600/
我正在尝试创建一个包含 int[][] 项的数组 即 int version0Indexes[][4] = { {1,2,3,4}, {5,6,7,8} }; int version1Indexes[
我有一个整数数组: private int array[]; 如果我还有一个名为 add 的方法,那么以下有什么区别: public void add(int value) { array[va
当您尝试在 JavaScript 中将一个数组添加到另一个数组时,它会将其转换为一个字符串。通常,当以另一种语言执行此操作时,列表会合并。 JavaScript [1, 2] + [3, 4] = "
根据我正在阅读的教程,如果您想创建一个包含 5 列和 3 行的表格来表示这样的数据... 45 4 34 99 56 3 23 99 43 2 1 1 0 43 67 ...它说你可以使用下
我通常使用 python 编写脚本/程序,但最近开始使用 JavaScript 进行编程,并且在使用数组时遇到了一些问题。 在 python 中,当我创建一个数组并使用 for x in y 时,我得
我有一个这样的数组: temp = [ 'data1', ['data1_a','data1_b'], ['data2_a','data2_b','data2_c'] ]; // 我想使用 toStr
rent_property (table name) id fullName propertyName 1 A House Name1 2 B
这个问题在这里已经有了答案: 关闭13年前。 Possible Duplicate: In C arrays why is this true? a[5] == 5[a] array[index] 和
使用 Excel 2013。经过多年的寻找和适应,我的第一篇文章。 我正在尝试将当前 App 用户(即“John Smith”)与他的电子邮件地址“jsmith@work.com”进行匹配。 使用两个
当仅在一个边距上操作时,apply 似乎不会重新组装 3D 数组。考虑: arr 1),但对我来说仍然很奇怪,如果一个函数返回一个具有尺寸的对象,那么它们基本上会被忽略。 最佳答案 这是一个不太理
我有一个包含 GPS 坐标的 MySQL 数据库。这是我检索坐标的部分 PHP 代码; $sql = "SELECT lat, lon FROM gps_data"; $stmt=$db->query
我需要找到一种方法来执行这个操作,我有一个形状数组 [批量大小, 150, 1] 代表 batch_size 整数序列,每个序列有 150 个元素长,但在每个序列中都有很多添加的零,以使所有序列具有相
我必须通过 url 中的 json 获取文本。 层次结构如下: 对象>数组>对象>数组>对象。 我想用这段代码获取文本。但是我收到错误 :org.json.JSONException: No valu
enter code here- (void)viewDidLoad { NSMutableArray *imageViewArray= [[NSMutableArray alloc] init];
知道如何对二维字符串数组执行修剪操作,例如使用 Java 流 API 进行 3x3 并将其收集回相同维度的 3x3 数组? 重点是避免使用显式的 for 循环。 当前的解决方案只是简单地执行一个 fo
已关闭。此问题需要 debugging details 。目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and the
我有来自 ASP.NET Web 服务的以下 XML 输出: 1710 1711 1712 1713
如果我有一个对象todo作为您状态的一部分,并且该对象包含数组列表,则列表内部有对象,在这些对象内部还有另一个数组listItems。如何更新数组 listItems 中 id 为“poi098”的对
我想将最大长度为 8 的 bool 数组打包成一个字节,通过网络发送它,然后将其解压回 bool 数组。已经在这里尝试了一些解决方案,但没有用。我正在使用单声道。 我制作了 BitArray,然后尝试
我们的数据库中有这个字段指示一周中的每一天的真/假标志,如下所示:'1111110' 我需要将此值转换为 boolean 数组。 为此,我编写了以下代码: char[] freqs = weekday
我是一名优秀的程序员,十分优秀!