C语言基础四(指针)
来源:互联网 发布:网络评论文章怎么写 编辑:程序博客网 时间:2024/05/26 07:28
指针
指针表示一个地址,什么类型的指针就应该指向什么类型的内存空间,例如int *类型的指针就应该指向一个int类型的空间。
int a = 7;int *p = NULL; //指针的定义p = &a; //指针的绑定*p = 5; //指针的解引用
指针的运算
对于同类型指针p1,p2,一般有这几种运算p1+3, p1-3, p2-p1int a[5] = {1, 2, 3, 4, 5};int *p1 = a; //p1指向第一个元素int *p2 = p1 + 3; //p2 指向第4个元素int c = p2 - p1; //=3,表示相差3个指针所指向的类型的空间。
指针数组和数组指针
int *p[5]; //指针数组,因为[]优先级比价高,所以p表示一个数组,里面存放5个int指针int (*p)[5]; //数组指针,p是一个指针,指向一个int[5]类型的空间
int **c;int a1[3] = {1, 2, 3}, a2[3] = {4, 5, 6};int b[2][3] = {a1, a2}; 等价于int b[2][3] = {1, 2, 3, 4, 5, 6};int (*p)[3] = b; //数组指针可以与二维数组匹配//*p 表示的是a1这个数组,*(p+1)表示a2这个数组。 **(p+1)表示的是a2中的第一个元素//这里的b和p在参与运算时,相当于二维指针,但是与 c 的类型是不同的,数组指针p指向int[3],c指向int *。
char (*p)[10];char arr[][10] = { "hello", "world",};//p是一个数组指针,他可以与二维数组arr匹配。 //这里每行的字符数必须确定,行数可以不用注明,//因为在内存中存放时都是以一维数组的形式按顺序排放的,每行字符数的增减直接影响到下一行的位置,//所以要想存储下一行,必须先确定了上一行的存储大小。char arr1[][5][10];//三维数组也必须要确定第二维和第三维的大小,可以与char (*q)[5][10]匹配;
指针的强制类型转换
对指针进行强制类型转换一般是需要 目标指针类型的偏移量 ,或者需要 等号两边的指针类型 相互匹配。
char arr[] = "abcdefghijk";int *p = (int *)arr + 1;printf("%c %c %c %c\n", *(char *)p, *((char *)p+1), *((char *)p+2), *((char *)p+3));//输出为e f g h
#define ADDR 0int *p = (int *)ADDR;
嵌入式是一种寄存器和内存统一编址的硬件设备,对寄存器读写操作时,可以直接对其地址进行操作。
假设地址是一个合法地址0x7FFF1234,这个地址的寄存器是32位寄存器,对这个寄存器读写操作
*(int *)0x7FFF1234 = 1;或者将其写成宏定义#define rG *((volatile unsigned int *)0x7FFF1234)int a = rG;rG = 1;//volatile 关键字,表示经常改变的,编译器不会做优化,每次都是从内存中重新读取数据。
函数指针
函数名就是函数的首地址
int * f(int a, int b); //这是一个返回值为int *类型的函数;int (*f1)(int a); //函数指针,f1是一个指针,指向类型是int (*)(int )
int max(int a, int b){ return a > b ? a : b; } int main() { int (*f)(int, int); //定义了一个函数指针,指向‘返回值类型为int,有两个参数类型都是int’的函数 f = max; //函数指针f指向函数max,或者写成f = &max; int c = f(1, 2); //或者写成c = (*f)(1, 2); printf("%d \n", c);
typedef
typedef int * p_int1;#define p_int2 int * p_int1 a, b; //相当于int *a, *b;p_int2 c, d; //相当于int *a, b;
//定义一个函数类型,理论上应该是typedef (void (*)(int , int )) FUNC1;但编译器编译不通过的,实际上应该写成typedef int (*FUNC2)(int , int );FUNC2是新类型名,代表了原类型int (*)(int , int )
typedef可以简化类型
typedef int (*FUNC)(int , int );int add(int a, int b){return a + b;}int sub(int a, int b){return a - b;}//定义一个返回值为FUNC类型的函数,返回值类型为int (*)(int , int )//int (*calculate(char operate))(int , int )//通过typedef可以简化成下面的定义。FUNC calculate(char operate){ switch(operate) { case '+': return add; case '-': return sub; dafault: return NULL; }}//最后还需定义一个用户调用的函数int cal(int a, int b, char operate){ FUNC fp = calculate(operate); //fp现在指向了加或者减的那个函数,或者指向NULL。 if(fp) return fp(a, b); else return -1;}
malloc和calloc
申请的是堆内存。堆内存不会自己释放,直到整个进程运行完毕。
所以malloc( )申请的空间一定要保存好这段空间的首地址,用完之后free( )释放.
函数原型void *malloc(unsigned int num_bytes);//申请成功,返回这段空间的首地址,不成功返回NULL地址为NULL的空间在内核区域,所以在申请时,一定要判断是否申请成功当申请的字节数为0时,也会申请出一个最小单位的空间,这个空间用来保存申请空间的大小。也可以用free()释放。int *p = (int *)malloc(sizeof(int) * 5); //在堆内存申请5个int空间if(NULL == p){ printf("malloc error\n"); return 0;}memset(p, 0, sizeof(int) * 5); //给这段空间清零。//用完这段空间之后free(p); //指针p在使用时不能移动,否则释放不彻底,会内存泄漏p = NULL;//防止野指针乱指。
NULL
NULL是一种地址类型的0,(void *)0.
表示内存中最低端,也是就系统内核最开始的地方。
const
const int a = 1; //a在C和C++中存储的方式有所不同。
对于全局变量或者静态变量,C和C++中都是存储在数据段,也就是全局/静态存储区;
对于局部变量
C语言中,和普通局部变量一样也是存储在栈区,
C++中对const进行了优化,如果初始化为常量表达式,将其视为标识符常量,和宏定义类似,编译时直接替换,这叫常量折叠。
宏定义是在预编译阶段进行字符替换,替换结束后,就会丢弃原字符。
如果通过 别的变量的值 或者 地址中的值 初始化,就是不可折叠常量。
<常量折叠>(constant folding),编译的时候,任何用到 “a” 的地方,都会直接用常量表达式的值 “1” 去替换。
这时候a的值不需要访问存储空间来确定,程序中任何出现 a 的地方在编译期间就已经被替换,即使通过取地址来修改这个值,也是相当于改变了一个副本而已,取地址时,编译器会为a另外分配空间。
C++中const定义的变量是可以用于定义数组的元素个数。而C语言就没有这个优化特性,所以C语言的const修饰的变量是不能用来定义数组元素个数的。
const修饰指针
const int *a; //*a(a指向的空间)是const的int const *a; //同上int * const a; //地址a是const的int **const*a; //*a(a指向的空间,类型是int **)是const的,int *const**a; //**a(a指向的空间内容所指向的空间,类型是int *)是const的,可以理解为,const修饰它之后的内容,可以将他之后的内容看作是指针运算的表达式(表示修饰的空间)
- C语言基础四(指针)
- c语言基础(四)之指针
- 【C语言复习(四)】指针基础
- C语言基础(四)指针 数组
- c语言基础(四)指针篇
- C语言基础(四)(指针)
- C语言基础 (四)指针与数组
- c语言 指针基础
- C语言指针基础
- C语言基础 指针
- C语言基础 --指针
- C语言基础-指针
- C语言指针基础
- C语言--指针基础
- C语言基础--指针
- C语言 基础(四)
- c语言指针(四)
- C指针基础(四)
- [HDU] 6231
- Centos7在安装配置redis
- 递归sql
- PHP操作redis
- enum
- C语言基础四(指针)
- 2017CCPC 秦皇岛一点总结
- gettools.exe 已停止工作
- HttpServlertRequest
- kivy踩坑记
- OpenCV--基本阈值操作
- 深度数据恢复软件6.3.2 让电脑硬盘 U盘 SD卡快速恢复
- 使用socket传输10M大小的图片
- B