C语言指针的初始化
1. C语言中指针的初始化问题
void main () { struct Person { char* name; char* sex; int age; }; struct Person p1; p1.name = "Fane"; p1.sex = "man"; p1.age = 22; printf("name is %s, sex is %s, age is %d", p1.name, p1.sex, p1.age); }
编译器编译运行上面代码,发现能够输出正确结果!
void main () { struct Person { char* name; char* sex; int age; } persons[1]; scanf("%s", persons[0].name); scanf("%s", persons[0].sex); scanf("%d", &persons[0].age); printf("name is %s, sex is %s, age is %d", persons[0].name, persons[0].sex, persons[0].age); }
运行这一段代码,会发现程序卡住,输入什么东西都没有反应。这两段代码咋看之下没什么区别,都是对一个结构体的变量赋值操作。但是我们会发现,在第一段代码中,有p1.name = "fane"
这种代码,而在第二段代码中,是通过scanf("%s", person[0].name);
把输入的值放入到name这个结构体成员指针指向的内存中。可是,此时person[0].name
有初始化吗?它指向了一个具体的内存地址吗?都没有,所以它指向的是个垃圾地址,是没有办法往这个内存地址写入值的。所以,请记住,C语言中的指针必须初始化才能被正常使用、访问。不管这个指针是什么类型。那为什么p1.name = "fane"
不会卡住呢?这是因为这句话本身就是一个初始化操作,就是在初始化p1.name这个指针指向某个内存地址。
C语言指针常量、常量指针
C语言里指针是个非常强大的存在。常用的有三种情况。
- 普通指针
- 常量指针
- 指针常量
普通指针
这种类型的指针所指向的值可被修改,指针也可被重新赋值。void main(){ char* p = (char*)malloc(sizeof(char)); // 指针p指向的值可被修改 memset(p, 0x00, sizeof(char)); // 指针p可被修改 char t = 'A'; p = &t; // p指向了t }
常量指针(const char*)(char const*)
注意:const在*前面就叫做常量指针,与char的位置无关
常量指针表示指针指向的值是个常量无法修改。但是指针可以被修改。ps:常量指针又被叫做只读指针,它可以被赋予一个新的地址,但是赋值新的地址之后还是不能修改指针指向的值。常量指针更多说明
void main(){ const char* p; // p是常量指针 char* m = "fane"; // m是常量指针 char const* n; // n是常量指针 int const number = 3, *t; // t是常量指针 }
指针常量(char* const p)(*char const q)
注意:*在const前面就叫做指针常量,与char的位置无关
指针常量表示指针是个常量,但是指针指向的值可以被修改。与常量指针情况恰好相反。void main(){ char* const p = (char*)malloc(sizeof(char)); // 情况一,p被重新赋值 char t = 'A'; p = &t; // 程序运行错误,因为p不可被改变 // 情况二,*p被重新赋值 *p = 'A'; *p = 'T'; // 程序正确运行 }
C语言在使用过程中,需要万分注意指针的类型,不然很多时候都不知道哪里错了。
eg.
#include <stdio.h> #include <string.h> void main(){ char* p = "fane"; char* q = "paul"; strcat(p, q); printf("strcat is %s\n", p); // 看看程序是否能如期输出,可以看看strcat()的源码,会发现要求的指针是否可写 }