void指针和const
1、学习目标
- void指针-掌握
- const修饰符-掌握
- 总结与思考
2、void指针
-
void指针是一种不确定数据类型的指针变量,它可以通过强制类型转换让该变量指向任何数据类型的变量。
-
一般形式为:void * <指针变量名称>;
-
示例:void指针在取值的时候必须做一个强制转换,赋值的时候可以省略
#include <stdio.h> int main() { int m = 10; double n = 3.14; void * p, * q; p = &m;// (void *)&m; printf("%d %d\n", m, *(int *)p); q = &n;// (void *)&n; printf("%.2lf %.2lf\n", n, *(double *)q); return 0; }
运行结果:
$ ./app 10 10 3.14 3.14
-
-
对于void指针,在没有强制类型转换之前,不能进行任何指针的算术运算。
-
示例:
#include <stdio.h> int main() { int m = 10; double n = 3.14; void * p, * q; p = &m;// (void *)&m; // printf("%d %d\n", m, *(int *)p); printf("%p\n", p); p++; printf("%p\n", p); q = &n;// (void *)&n; // printf("%.2lf %.2lf\n", n, *(double *)q); printf("%p\n", q); q++; printf("%p\n", q); return 0; }
运行结果:结果是错误的,指针加1移动一个元素,在64位机中移动8个字节,在32位机中移动4个字节,下面的打印结果是移动一个字节,所以说打印结果是错误的,void指针,在没有强制类型转换之前,不能进行任何指针的算术运算。
$ ./app 0x7fffe3eb278c 0x7fffe3eb278d 0x7fffe3eb2790 0x7fffe3eb2791
-
-
程序举例
-
编程实现:使用void指针遍历一维数组。
#include <stdio.h> int main() { int a[] = {5,9,1,6,9,10}; int i, n; void * p; p = a; n = sizeof(a)/sizeof(int); for(i = 0; i < n; i++) printf("%d ", *((int *)p + i)); puts(""); return 0; }
运行结果:
$ ./app 5 9 1 6 9 10
-
-
void的其他用法
- void * malloc(size_t siae);动态内存函数
- int pthread_create(pthread_t *thread, conts pthread_attr_t * attr, void * (*start_routine)(void *),void * arg);线程创建函数
- void qsort(void *base, size_t nmemb, size_t size,int( *compar)(const void *, const void *));快速排序函数
3、const变量
-
常量化变量的值
-
一般形式如下:
- const <数据类型> 变量名 = [<表达式>];
-
常量化变量是为了使得变量的值不能修改
-
关于const的基础程序说明
#include <stdio.h> int main() { const int m = 10; m++; return 0; }
运行结果:m是只读变量,const修饰变量m,m成为常量,常量不能进行加减运算。
const1.c: In function ‘main’: const1.c:7:3: error: increment of read-only variable ‘m’ m++; ^
-
-
变量有const修饰时,若想用指针间接访问变量,指针也要有const修饰。const放在指针声明的什么位置呢?const修饰谁,谁不能变
-
常量化指针变量
一般说明形式如下:
<数据类型> * const <指针变量名称> [= <指针运算表达式>]
使得<指针变量>存储的地址值不能修改,但可以通过* <指针变量名称>可以修改指针所指向变量的数值。
#include <stdio.h> int main() { int m = 10; int * const q = &m;//正确,可以通过* const q修改指针所指向变量的数值。 // q = &m;//错误的,q是只读变量,不能进行修改 *q = 20;//正确的 return 0; }
-
常量化指针目标表达式
一般说明形式如下:
const <数据类型> * <指针变量名称> [= <指针运算表达式>];
常量化指针目标是限制通过指针改变其目标的数值,但<指针变量>存储的地址值可以修改。
#include <stdio.h> int main() { int m = 10; const int * p; p = &m;//right (*p)++;//error,*p为只读变量,不能修改 return 0; }
-
常量化指针变量及目标表达式
一般说明形式如下:
const <数据类型> * const <指针变量名称> [= <指针运算表达式>];
常量化指针变量及其目标表达式,使得既不可以修改<指针变量>的地址,也不可以通过*<指针变量名称>修改指针所指向变量的值。
#include <stdio.h> int main() { int m = 10; const int * const r = &m; r++;//error (*r)++;//error, r,*r 均为常量 return 0; }
-
三种情况归纳如下:
#include <stdio.h> int main() { int m = 10; const int * p; int * const q = &m; const int * const r = &m; p = &m;//right // (*p)++;//error // q = &m;//error *q = 20;//right r++;//error (*r)++;//error, r,*r 均为常量 return 0; }
-
4、总结与思考
-
主要介绍了const修饰指针的用法,有三种情况,以及介绍了void指针的用法。
-
思考:
-
void指针有什么用?
使指针更加具有通用性。
-
main函数是否可以带参数(涉及到const指针)?
#include <stdio.h> int main(int argc, const char * argv[]) { //const char * argv[] = {"./app","192.168.1.7","999"}; int i; printf("argc = %d\n", argc); for(i = 0; i < argc; i++){ printf("%s\n", argv[i]); } return 0; }
运行结果:可以
$ ./app 192.168.1.7 999 argc = 3 ./app 192.168.1.7 999
-