c/c++语言 指针赋值问题
2013-12-16 19:54
295 查看
昨天遇到一个指针赋值问题,一开始看代码好像没有错误,而且编译也通过了,运行确错误了,这不很奇怪吗?比如下面这个例子:
#include <stdio.h>
int main(void)
{
int j;
char *ch1[4] = {"hello", "hi", "ok", "yes"};
char *ch2[4] = {"HELLO", "HI", "OK", "YES"};
char **p1;
*p1 = ch1[1];
printf("%s\n", *p1);
return 0;
}
这个例子够简单吧。
初略分析下:
p1是一个指针,该指针的类型是char **,该指针指向的类型是char *;
*p1也是一个指针,该指针的类型是char *,该指针指向的类型是char。
而ch1是一个4元数组,该数组中存放的是指向char类型的指针。
若把ch1当做指针来看,那么ch1的类型是char **,ch1指向的类型是char *;*ch1等价于*(ch1+0)也等价于ch1[0],那么ch1[0]是什么呢?刚说过了,ch1是一个存放指针的4元数组,所以,ch1[0]存放的是"hello"的首地址,即字符h的地址。
这样一来,ch1[0]指针的类型是char *,该指针指向的类型是char。
看来指针*p1和ch1[0]的类型相同,他们指向的类型也相同,把ch1[0]赋值给*p1当然没问题了。那么程序为什么还出错呢?
仔细分析下便知道,其实p1是一个野指针,因为p1根本就没有初始化,它的地址是不确定的,也许这个地址是不能使用的。所以程序会出错。
给成如下形式便ok了:
#include <stdio.h>
int main(void)
{
int j;
char *ch1[4] = {"hello", "hi", "ok", "yes"};
char *ch2[4] = {"HELLO", "HI", "OK", "YES"};
char **p1 = ch2;
*p1 = ch1[0];
printf("%s\n", *p1);
return 0;
}
运行下,结果出来了吧。程序在声明初始化指针p1的时候,把ch2的地址赋给了p1,那么*p1指向了ch2[0]所在的内存区。执行了语句*p1=ch1[0]后,指针ch2[0]不在指向"HELLO"而是指向"hello"了,你可以用循环语句输出结果看看:
#include <stdio.h>
int main(void)
{
int j;
char *ch1[4] = {"hello", "hi", "ok", "yes"};
char *ch2[4] = {"HELLO", "HI", "OK", "YES"};
char **p1 = ch2;
*p1 = ch1[0];
for(j = 0; j < 4; j++)
printf("%s\n", *p1++);
return 0;
}
关于指针赋值总结下:
1. 指针的赋值
int a = 4;
int *ptr = &a; //指针声明并初始化赋值
上面这一句等价于:
int *ptr;
prt = &a;
2. 以下是错误的赋值
int *ptr = 4;
或者
int *prt;
*ptr = 4;
因为此时的ptr是个野指针,ptr所指向的地址不确定。
3. 下面的赋值却是正确的
int *ptr = "hello";
或者
int *ptr;
ptr = "hello";
因为编译器将数组或者字符串解析为地址,编译时编译器将字符串存储在静态存储区。
在第一个声明中,看上去初始值是赋给表达式*prt的,事实上它是赋给ptr本身的。在字符串表达式中,表达式所使用的值就是这些字符所存储的地址,而不是这些字符本身。从第二种赋值方法中我们也可以明白这一点。
#include <stdio.h>
int main(void)
{
int j;
char *ch1[4] = {"hello", "hi", "ok", "yes"};
char *ch2[4] = {"HELLO", "HI", "OK", "YES"};
char **p1;
*p1 = ch1[1];
printf("%s\n", *p1);
return 0;
}
这个例子够简单吧。
初略分析下:
p1是一个指针,该指针的类型是char **,该指针指向的类型是char *;
*p1也是一个指针,该指针的类型是char *,该指针指向的类型是char。
而ch1是一个4元数组,该数组中存放的是指向char类型的指针。
若把ch1当做指针来看,那么ch1的类型是char **,ch1指向的类型是char *;*ch1等价于*(ch1+0)也等价于ch1[0],那么ch1[0]是什么呢?刚说过了,ch1是一个存放指针的4元数组,所以,ch1[0]存放的是"hello"的首地址,即字符h的地址。
这样一来,ch1[0]指针的类型是char *,该指针指向的类型是char。
看来指针*p1和ch1[0]的类型相同,他们指向的类型也相同,把ch1[0]赋值给*p1当然没问题了。那么程序为什么还出错呢?
仔细分析下便知道,其实p1是一个野指针,因为p1根本就没有初始化,它的地址是不确定的,也许这个地址是不能使用的。所以程序会出错。
给成如下形式便ok了:
#include <stdio.h>
int main(void)
{
int j;
char *ch1[4] = {"hello", "hi", "ok", "yes"};
char *ch2[4] = {"HELLO", "HI", "OK", "YES"};
char **p1 = ch2;
*p1 = ch1[0];
printf("%s\n", *p1);
return 0;
}
运行下,结果出来了吧。程序在声明初始化指针p1的时候,把ch2的地址赋给了p1,那么*p1指向了ch2[0]所在的内存区。执行了语句*p1=ch1[0]后,指针ch2[0]不在指向"HELLO"而是指向"hello"了,你可以用循环语句输出结果看看:
#include <stdio.h>
int main(void)
{
int j;
char *ch1[4] = {"hello", "hi", "ok", "yes"};
char *ch2[4] = {"HELLO", "HI", "OK", "YES"};
char **p1 = ch2;
*p1 = ch1[0];
for(j = 0; j < 4; j++)
printf("%s\n", *p1++);
return 0;
}
关于指针赋值总结下:
1. 指针的赋值
int a = 4;
int *ptr = &a; //指针声明并初始化赋值
上面这一句等价于:
int *ptr;
prt = &a;
2. 以下是错误的赋值
int *ptr = 4;
或者
int *prt;
*ptr = 4;
因为此时的ptr是个野指针,ptr所指向的地址不确定。
3. 下面的赋值却是正确的
int *ptr = "hello";
或者
int *ptr;
ptr = "hello";
因为编译器将数组或者字符串解析为地址,编译时编译器将字符串存储在静态存储区。
在第一个声明中,看上去初始值是赋给表达式*prt的,事实上它是赋给ptr本身的。在字符串表达式中,表达式所使用的值就是这些字符所存储的地址,而不是这些字符本身。从第二种赋值方法中我们也可以明白这一点。
相关文章推荐
- C++ 指针 赋值基本问题
- (2011.07.06)C++ 结构体中字符指针在main中使用new的赋值问题。
- [笔试题 2][c/c++]关于指针直接赋值问题
- 【C++】使用局部变量赋值而非引用,导致内存多次释放的野指针问题
- [笔试题 2][c/c++]关于指针直接赋值问题
- 【C++】使用局部变量赋值而非引用,导致内存多次释放的野指针问题
- [笔试题 2][c/c++]关于指针直接赋值问题
- C++中 关于结构体中有char *类型的指针 赋值问题
- C/C++语言void及void指针深层探索
- C/C++语言void及void指针深层探索
- C/C++中指针和引用之相关问题研究
- c语言打印字符乱码和char *字符循环赋值时“段错误 (核心已转储)”问题解决
- C++指针和作用域的问题
- C/C++语言void及void指针深层探索
- 关于数组给指针赋值的问题
- C/C++语言void及void指针深层探索
- C 语言中返回一个指向自动变量的指针存在的问题
- C/C++语言void及void指针深层探索
- C/C++函数指针参数不匹配问题
- 从链表操作理解C++传指针的问题