常量指针与常量变量

时间:2014-03-06 15:48:09

标签: c

我是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; 
} 

另外,mystrmystr[2]有什么不同(每个变量的数据类型是什么),p_mystr = mystr[2];是否有任何错误可以写得更好(即:为什么是{{ 1}}正确)?

3 个答案:

答案 0 :(得分:0)

变量mystrstr2都是存储在堆栈中的字符数组。除了用于初始化字符数组的字符串文字外,这里没有任何“常量”。


p_mystr是一个指针,mystr[2]是一个字符。 哪里是你的*p_mystr= mystr[2];应该是什么?最好不要在 p_mystr初始化为有效地址之前

答案 1 :(得分:0)

你刚问了一口!

  1. 指针是一种与简单数据类型(char *与char相比)非常不同的类型。 char只有一个值,例如'一个'。您可以将指针视为内存地址 - 这意味着,转到内存地址0x0123F1A并将您在那里找到的内容视为char。指针可能很棘手,因此值得阅读,例如 here
  2. mystr是一个字符数组。在某些方面,它的行为类似于指向数组中第一个项目的指针,但它确实是一种独特的类型。 mystr [2]有char类型 - 它是在数组中索引2处找到的char(即第三个char,因为数组索引从0开始)。
  3. p_mystr = mystr没有任何问题 - 可以安全地从char数组赋值给char-pointer,其含义是使指针指向数组中的第一项。
  4. * p_mystr = mystr [2]意味着别的东西。 *运算符表示“指向的值”,所以这意味着“在p_mystr指向的内存地址中,复制字符mystr [2]”

答案 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(更改指向的内容);
  • 您可以写信至*p0p1(将其更改为指向其他内容),但您无法写信至p2*p1(无法更改内容指向);
  • 您无法写入*p2(无法将其更改为指向其他内容),但您可以写入p3(更改指向的内容);
  • 您无法写信至*p3p4(无法将其更改为指向其他内容),也无法写信至p5*p4(无法更改内容)被指出)。

所以,如果你声明了像

这样的东西
*p5

您无法通过const char *cptr = mystr; 变量修改mystr的内容,即使cptr本身未声明mystr

请注意,尝试采用其他方式,例如

const

调用未定义的行为;它可能有效也可能无效,具体取决于实现(语言定义允许实现将const int foo = 5; int *fptr = (int *) &foo; *fptr = 6; - 限定对象放在只读内存中。)

<小时/> 1。 如果 const指向某个地方有效,那就是。