char* 和 int* 之间的解引用运算符 (*) 区别
Dereference operator (*) differences between char* and int*
为什么运算符 (*
) 需要访问 int*
变量的值而不是 char*
?
char *char_ptr;
int *int_ptr;
int mem_size = 50;
char_ptr = (char *) malloc(mem_size);
strcpy(char_ptr, "This is memory is located on the heap.");
printf("char_ptr (%p) --> '%s'\n", char_ptr, char_ptr);
int_ptr = (int *) malloc(12);
*int_ptr = 31337;
printf("int_ptr (%p) --> %d\n", int_ptr, *int_ptr);
输出:
char_ptr (0x8742008) --> 'This is memory is located on the heap.'
int_ptr (0x8742040) --> 31337
您也可以使用表达式 *char_ptr
。它具有 char
类型,表达式将产生指向的字符 'T'
- 存储的字符串文字的第一个字符。
这与*int_ptr
相同,即returns分配整数数组的第一个元素。
至于转换说明符 %s
那么它需要一个指向字符串的 char * 类型的参数。另一方面,转换说明符 %d
期望类型为 int
的对象
您可以使用转换说明符 %c
。只输出指向字符串的单个字符,如
printf( "%c", *char_ptr );
这是因为 printf
格式说明符的工作方式:%s
格式期望,对于其相应的参数,一个指向字符的 指针 (更准确地说,是 nul
终止的 string - which can be an array of char
, an allocated buffer with at least one zero byte in it, or a string literal 的地址),所以你可以按原样给它 char_ptr
变量;另一方面,%d
格式需要一个 整数 (不是指向整数的指针),因此您必须使用 int_ptr
变量取消引用 *
运算符.
关于良好编程风格的注意事项:如您问题的评论中所述,请务必在分配给 malloc
的每个缓冲区上的某个时刻调用 free()
,否则您会介绍memory leaks into your code. Also see: Do I cast the result of malloc?.
对于任何指针或数组 p
和索引 i
,表达式 p[i]
正好等于 *(p + i)
。由此得出 *p
等于 p[0]
.
在你的例子中 *int_ptr
等于 int_ptr[0]
。
如果你对 char_ptr
做同样的事情(即 *char_ptr
)你会得到 char_ptr[0]
这是一个单一的字符,也可以用 %d
打印:
printf("char_ptr (%p) --> '%d'\n", char_ptr, *char_ptr);
这将打印字符串中第一个字符的十进制表示形式。
"Why is operator (*
) needed to access the value of an int*
variable and not for char*
?"
因为在 printf()
函数中,格式说明符 %s
需要一个 char *
类型的匹配参数 - 一个指向字符串的指针,而 %d
需要一个参数类型 int
.
在后一种情况下,解引用运算符 *
需要解引用 int_ptr
并产生 int
对象 int_ptr
指向的值。
因为 char_ptr
已经是 %s
所要求的 char*
类型,所以没有必要取消引用它。
旁注:
1.
int_ptr = (int *) malloc(12);
请注意,在大多数现代系统上使用 12
字节,您只能分配 1 个 int
对象,因为它需要 8
字节。剩余的 4
字节不足以容纳另一个字节。
如果您只想为一个 int
分配 space,请使用 sizeof(*int_ptr)
:
int_ptr = (*int) malloc(sizeof(*int_ptr));
2.
另外不要忘记 free()
malloc()
使用后分配的存储空间:
free(int_ptr);
free(char_ptr);
3.
此外,无需转换 malloc()
的 return 值:Do I cast the result of malloc?
char_ptr = malloc(mem_size);
int_ptr = malloc(sizeof(*int_ptr));
为什么运算符 (*
) 需要访问 int*
变量的值而不是 char*
?
char *char_ptr;
int *int_ptr;
int mem_size = 50;
char_ptr = (char *) malloc(mem_size);
strcpy(char_ptr, "This is memory is located on the heap.");
printf("char_ptr (%p) --> '%s'\n", char_ptr, char_ptr);
int_ptr = (int *) malloc(12);
*int_ptr = 31337;
printf("int_ptr (%p) --> %d\n", int_ptr, *int_ptr);
输出:
char_ptr (0x8742008) --> 'This is memory is located on the heap.'
int_ptr (0x8742040) --> 31337
您也可以使用表达式 *char_ptr
。它具有 char
类型,表达式将产生指向的字符 'T'
- 存储的字符串文字的第一个字符。
这与*int_ptr
相同,即returns分配整数数组的第一个元素。
至于转换说明符 %s
那么它需要一个指向字符串的 char * 类型的参数。另一方面,转换说明符 %d
期望类型为 int
您可以使用转换说明符 %c
。只输出指向字符串的单个字符,如
printf( "%c", *char_ptr );
这是因为 printf
格式说明符的工作方式:%s
格式期望,对于其相应的参数,一个指向字符的 指针 (更准确地说,是 nul
终止的 string - which can be an array of char
, an allocated buffer with at least one zero byte in it, or a string literal 的地址),所以你可以按原样给它 char_ptr
变量;另一方面,%d
格式需要一个 整数 (不是指向整数的指针),因此您必须使用 int_ptr
变量取消引用 *
运算符.
关于良好编程风格的注意事项:如您问题的评论中所述,请务必在分配给 malloc
的每个缓冲区上的某个时刻调用 free()
,否则您会介绍memory leaks into your code. Also see: Do I cast the result of malloc?.
对于任何指针或数组 p
和索引 i
,表达式 p[i]
正好等于 *(p + i)
。由此得出 *p
等于 p[0]
.
在你的例子中 *int_ptr
等于 int_ptr[0]
。
如果你对 char_ptr
做同样的事情(即 *char_ptr
)你会得到 char_ptr[0]
这是一个单一的字符,也可以用 %d
打印:
printf("char_ptr (%p) --> '%d'\n", char_ptr, *char_ptr);
这将打印字符串中第一个字符的十进制表示形式。
"Why is operator (
*
) needed to access the value of anint*
variable and not forchar*
?"
因为在 printf()
函数中,格式说明符 %s
需要一个 char *
类型的匹配参数 - 一个指向字符串的指针,而 %d
需要一个参数类型 int
.
在后一种情况下,解引用运算符 *
需要解引用 int_ptr
并产生 int
对象 int_ptr
指向的值。
因为 char_ptr
已经是 %s
所要求的 char*
类型,所以没有必要取消引用它。
旁注:
1.
int_ptr = (int *) malloc(12);
请注意,在大多数现代系统上使用 12
字节,您只能分配 1 个 int
对象,因为它需要 8
字节。剩余的 4
字节不足以容纳另一个字节。
如果您只想为一个 int
分配 space,请使用 sizeof(*int_ptr)
:
int_ptr = (*int) malloc(sizeof(*int_ptr));
2.
另外不要忘记 free()
malloc()
使用后分配的存储空间:
free(int_ptr);
free(char_ptr);
3.
此外,无需转换 malloc()
的 return 值:Do I cast the result of malloc?
char_ptr = malloc(mem_size);
int_ptr = malloc(sizeof(*int_ptr));