指针的理解\const修饰符

时间:2022-04-02 21:06:43
我觉得指针就是一个地址。问题是什么是指针,在程序中。比如说我们写出了这样的定义:char *p;到底p是指针,还是*p是指针,也就是说p代表了地址,还是*p代表了地址?一般的时候这个问题还容易解决p是地址嘛,不过我不知道是不是有很多人认为*p是地址。实际上到底哪个是地址我也不知道,我觉得应该是p是指针,也是地址。这是第一个问题:)
    第二个问题是和const有关,const到底是什么意思呢?

我们可以写出如下的程序:
#include <stdio.h>

void show_message(const char *p)
{
  while(*p != '\0')
  {
    printf("%c",*p++);
  }
}

int main()
{
  char *p = (char*)malloc(sizeof(char));
  p = "hello world\n";
  show_message(p);
//  show_message(p);
}
这个程序有问题吗?也许有问题,比如说我们定义了函数的参数为指针类型,关键是我们不允许这个参数发生变化(使用const来修饰的),如果执行如下的程序,在Linux,gcc下,会得到一个编译警告,但是可以编译成功:

#include <stdio.h>

void const_test(const int i)
{
   i++;
   printf("\n%i\n",i);
}

int main()
{
  int m= 0;
  const_test(m);
  printf("\n%i\n",m);
}

test.c: In function `const_test':
test.c:5: warning: increment of read-only location
执行的结果是:
1
0
从这个程序的执行结果看,函数传递了一个值copy给函数。而不增加const修饰符,会得到同样的结果,只是少了一个编译错误而已。
请高手指点

6 个解决方案

#1


i++改变的是i的值,而*p++改的是p的值(虽然没有改变指向的内容的值,但是我们传递进来的是一个地址,一个指针,他的值-内容-还是给改变了),为什么*p++没有编译警告,而i++有编译警告呢?

#2


第一个问题很简单,char *p,p是指针,体现为指向char的一个地址

下来的问题我自己试了下,在gcc中根本不是你说得那样,就是编译错误,不是警告(你用的gcc是什么版本的,还有你是不是用了一些附加的编译选项了,这种明显的错误怎么可能会是警告?)

下来的问题
printf("%c",*p++);
先分两步看,printf("%c",*p);p++;
没什么问题呀,先打印*p,然后把指针后移,由于while循环,继续打印后面一个字符,一起ok.
至于你的分析,不懂。

#3


gcc (GCC) 3.2 20020903 (Red Hat Linux 8.0 3.2-7)
Copyright (C) 2002 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

#4


"const指针的准确提法应该是指向const数据的指针,即它所指向的数据不能被修改。只要在指针说明的开头加入const修饰符,就可说明一个cosnt指针。尽管const指针所指向的数据不能被修改,但cosnt指针本身是可以修改的。"这是我刚从网上找到的答案^_^

#5


第一个问题:p是一个指针,编译的时候会在栈上为这个指针分配一个空间,这个空间的大小跟编译器有关,一般是2个或4个字节,用来存放p所指向空间的地址。*p是p指向空间所存放的值。
第二个问题,gcc下编译应该是一个error吧。
void const_test(const int i)
{
   i++;
   printf("\n%i\n",i);
}
const int i作为参数的话,i在函数内部是不应该作为左值的,否则就是一个编译错误。

void show_message(const char *p)
{
  while(*p != '\0')
  {
    printf("%c",*p++);
  }
}
是没有问题的,const char *p指的是p指向内容应该是常量,而p不是,所以p可以作为左值,*p++结合顺序是*(p++),所以是没有错的。

还有
int main()
{
  char *p = (char*)malloc(sizeof(char));//这个是没有必要的,字符串是常量,不在堆上分配。
  p = "hello world\n";
  show_message(p);
//  show_message(p);
}

#6


p是指针变量,即指针,存放的是地址,*是解引用符号,*p是p所指向的内存空间的值。

#1


i++改变的是i的值,而*p++改的是p的值(虽然没有改变指向的内容的值,但是我们传递进来的是一个地址,一个指针,他的值-内容-还是给改变了),为什么*p++没有编译警告,而i++有编译警告呢?

#2


第一个问题很简单,char *p,p是指针,体现为指向char的一个地址

下来的问题我自己试了下,在gcc中根本不是你说得那样,就是编译错误,不是警告(你用的gcc是什么版本的,还有你是不是用了一些附加的编译选项了,这种明显的错误怎么可能会是警告?)

下来的问题
printf("%c",*p++);
先分两步看,printf("%c",*p);p++;
没什么问题呀,先打印*p,然后把指针后移,由于while循环,继续打印后面一个字符,一起ok.
至于你的分析,不懂。

#3


gcc (GCC) 3.2 20020903 (Red Hat Linux 8.0 3.2-7)
Copyright (C) 2002 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

#4


"const指针的准确提法应该是指向const数据的指针,即它所指向的数据不能被修改。只要在指针说明的开头加入const修饰符,就可说明一个cosnt指针。尽管const指针所指向的数据不能被修改,但cosnt指针本身是可以修改的。"这是我刚从网上找到的答案^_^

#5


第一个问题:p是一个指针,编译的时候会在栈上为这个指针分配一个空间,这个空间的大小跟编译器有关,一般是2个或4个字节,用来存放p所指向空间的地址。*p是p指向空间所存放的值。
第二个问题,gcc下编译应该是一个error吧。
void const_test(const int i)
{
   i++;
   printf("\n%i\n",i);
}
const int i作为参数的话,i在函数内部是不应该作为左值的,否则就是一个编译错误。

void show_message(const char *p)
{
  while(*p != '\0')
  {
    printf("%c",*p++);
  }
}
是没有问题的,const char *p指的是p指向内容应该是常量,而p不是,所以p可以作为左值,*p++结合顺序是*(p++),所以是没有错的。

还有
int main()
{
  char *p = (char*)malloc(sizeof(char));//这个是没有必要的,字符串是常量,不在堆上分配。
  p = "hello world\n";
  show_message(p);
//  show_message(p);
}

#6


p是指针变量,即指针,存放的是地址,*是解引用符号,*p是p所指向的内存空间的值。