我是C编程的新手,我想知道在这种情况下指针常量与常量变量的区别如何:
#include <stdio.h>
int main(void)
{
int cnt = 0;
char val;
char mystr[20] = “hello there!”;
char *p_str2, str2[20] = “zzzzzzzzzzzzzzzz”;
char* p_mystr = mystr;
p_str2 = str2;
while (*p_mystr != 0x00)
{
val=*p_mystr++;
cnt++;
}
return 0;
}
另外,mystr
与mystr[2]
有什么不同(每个变量的数据类型是什么),p_mystr = mystr[2];
是否有任何错误可以写得更好(即:为什么是{{ 1}}正确)?
答案 0 :(得分:0)
变量mystr
和str2
都是存储在堆栈中的字符数组。除了用于初始化字符数组的字符串文字外,这里没有任何“常量”。
p_mystr
是一个指针,mystr[2]
是一个字符。 哪里是你的*p_mystr= mystr[2];
应该是什么?最好不要在 p_mystr
初始化为有效地址之前。
答案 1 :(得分:0)
你刚问了一口!
答案 2 :(得分:0)
除非它是sizeof
或一元&
运算符的操作数,否则“{元素数组T
”类型的表达式将是转换为“指向T
的指针”的表达式,表达式的值将是数组的第一个元素的地址。结果不是左值,这意味着它不能作为赋值的目标。
所以,鉴于声明
char mystr[20] = "hello there!";
以下都是真的:
Expression Type Decays to Result
---------- ---- --------- ------
mystr char [20] char * address of mystr[0]
&mystr char (*)[20] n/a address of mystr
*mystr char n/a value of mystr[0], or 'h'
mystr[i] char n/a i'th character
&mystr[i] char * n/a address of mystr[i]
sizeof mystr size_t n/a 20 (number of bytes in array)
数组的地址与数组的第一个元素的地址相同(没有为与数组元素本身分开的mystr
变量留出存储空间),因此表达式{{1} },mystr
和&mystr
都返回相同的值,但表达式的类型不同; &mystr[0]
和mystr
都有&mystr[0]
类型,但char *
的类型为&mystr
,或“指向char (*)[20]
的20个元素数组的指针”。
char
的结果是相同的。
鉴于声明
str2
我们得到以下
char *p_mystr;
Expression Type Result
---------- ---- ------
p_mystr char * value in p_mystr
*p_mystr char value of character pointed to by p_mystr
&p_mystr char ** address of p_mystr variable
sizeof p_mystr size_t number of bytes in pointer value
的表格是相同的。
现在这是匹配类型的问题。 p_str2
有效,因为两个表达式的类型都为p_mystr = mystr
; char *
指向p_mystr
。同样,mystr[0]
的工作原理是 1 ,因为两个表达式的类型都为*p_mystr = mystr[2]
。 char
也是如此,但在这种情况下请注意val = *p_mystr++
被解析为*p_mystr++
;增量将应用于指针值,而不是字符值。
请注意,*(p_mystr++)
之类的表达式可以让您诊断出类型不匹配的效果。
您的问题标题提到了p_mystr = &mystr;
指针和变量,尽管这不会出现在问题正文中。基本上,对于任何类型const
:
T
分解为:
T *p0; // p0 is a non-const pointer to non-const T
const T *p1; // p1 is a non-const pointer to const T
T const *p2; // p2 is a non-const pointer to const T
T * const p3; // p3 is a const pointer to non-const T
const T * const p4; // p4 is a const pointer to const t
T const * const p5; // p5 is a const pointer to const t
(将其更改为指向其他内容)和p0
(更改指向的内容); *p0
和p1
(将其更改为指向其他内容),但您无法写信至p2
或*p1
(无法更改内容指向); *p2
(无法将其更改为指向其他内容),但您可以写入p3
(更改指向的内容); *p3
或p4
(无法将其更改为指向其他内容),也无法写信至p5
或*p4
(无法更改内容)被指出)。 所以,如果你声明了像
这样的东西*p5
您无法通过const char *cptr = mystr;
变量修改mystr
的内容,即使cptr
本身未声明mystr
。
请注意,尝试采用其他方式,例如
const
调用未定义的行为;它可能有效也可能无效,具体取决于实现(语言定义允许实现将const int foo = 5;
int *fptr = (int *) &foo;
*fptr = 6;
- 限定对象放在只读内存中。)
const
指向某个地方有效,那就是。