简短的回答是:不要。 ;-) 指针用于不能使用其他任何东西的地方。这要么是因为缺乏适当的功能、缺少数据类型,要么是纯粹为了性能。更多下文...
简短的回答是:你不能使用其他任何东西的地方。在 C 中,您不支持复杂的数据类型,例如字符串。也无法将变量“通过引用”传递给函数。这就是你必须使用指针的地方。您还可以让它们指向几乎任何东西,链表、结构成员等等。但我们这里不讨论这个。
花费很少的努力和很多混乱。 ;-) 如果我们谈论简单的数据类型,例如 int 和 char,数组和指针之间几乎没有什么区别。
这些声明非常相似(但不相同 - 例如,sizeof
将返回不同的值):
char* a = "Hello";
char a[] = "Hello";
您可以像这样访问数组中的任何元素
printf("Second char is: %c", a[1]);
索引 1,因为数组从元素 0 开始。:-)
或者你也可以这样做
printf("Second char is: %c", *(a+1));
需要指针运算符(*),因为我们告诉 printf 我们要打印一个字符。如果没有 *,将打印内存地址本身的字符表示形式。现在我们使用角色本身。如果我们使用 %s 而不是 %c,我们会要求 printf 打印 'a' 加一所指向的内存地址的内容(在上面的示例中),并且我们不必将 *在前:
printf("Second char is: %s", (a+1)); /* WRONG */
但这不会只打印第二个字符,而是打印下一个内存地址中的所有字符,直到找到空字符(\0)。这就是事情开始变得危险的地方。如果您不小心尝试使用 %s 格式化程序打印整数类型的变量而不是字符指针怎么办?
char* a = "Hello";
int b = 120;
printf("Second char is: %s", b);
这将打印在内存地址 120 上找到的任何内容,并继续打印直到找到空字符。执行此 printf 语句是错误且非法的,但它可能会起作用,因为在许多环境中指针实际上是 int 类型。想象一下,如果您改用 sprintf() 并将这种太长的“char 数组”分配给另一个变量,而该变量仅分配了一定的有限空间,则可能会导致问题。您很可能最终会覆盖内存中的其他内容并导致您的程序崩溃(如果您幸运的话)。
哦,如果在声明时没有为 char 数组/指针分配字符串值,则必须在为其赋值之前为其分配足够的内存。使用 malloc、calloc 或类似的。这是因为您只声明了数组中的一个元素/一个要指向的内存地址。这里有几个例子:
char* x;
/* Allocate 6 bytes of memory for me and point x to the first of them. */
x = (char*) malloc(6);
x[0] = 'H';
x[1] = 'e';
x[2] = 'l';
x[3] = 'l';
x[4] = 'o';
x[5] = '\0';
printf("String \"%s\" at address: %d\n", x, x);
/* Delete the allocation (reservation) of the memory. */
/* The char pointer x is still pointing to this address in memory though! */
free(x);
/* Same as malloc but here the allocated space is filled with null characters!*/
x = (char *) calloc(6, sizeof(x));
x[0] = 'H';
x[1] = 'e';
x[2] = 'l';
x[3] = 'l';
x[4] = 'o';
x[5] = '\0';
printf("String \"%s\" at address: %d\n", x, x);
/* And delete the allocation again... */
free(x);
/* We can set the size at declaration time as well */
char xx[6];
xx[0] = 'H';
xx[1] = 'e';
xx[2] = 'l';
xx[3] = 'l';
xx[4] = 'o';
xx[5] = '\0';
printf("String \"%s\" at address: %d\n", xx, xx);
请注意,在对分配的内存执行 free() 后,您仍然可以使用变量 x,但您不知道其中有什么。另请注意,两个 printf() 可能会给出不同的地址,因为不能保证第二次内存分配与第一次分配在同一空间中执行。