Linux 第六课
来源:互联网 发布:台湾绿瓦5.5膛线数据 编辑:程序博客网 时间:2024/05/17 06:26
如何避免野指针
1.当我们定义一个指针时,如果这个指针没有指向,要置空
//#define NULL (void *)0char *p = NULL;
对指针置空,有利于提醒我们不对零地址操作,另外,当出运行出现段错误时方便检查是否对零地址操作。
零地址:不可以进行复制操作,也不可以对零地址内的值进行修改。初始化为零地址(NULL),让我们形成条件反射,不能对零地址进行操作
2.在使用指针之前要检查指针是否合法,如果为零地址,就要用malloc进行分配。
#define MAX_SIZE 100char *ptr;ptr = (char *)malloc(sizeof(char) * MAX_SIZE);
分配完后要检查是否分配成功
if(ptr ==NULL){ printf("error!"); exit(1);}
malloc 函数的原型
void *malloc(size_t size);
void 是万能指针,可以接受任何类型的指针,但是不能取值。
*使用malloc之前为什么要进行强制类型转换?
因为C语言中指针的赋值一定要是相同类型指针之间的赋值。如果不是相同指针类型就会出现越界(将步长小的指针赋值给步长大的指针)或丢失(将步长大的指针赋值给步长小的指针)
3.在使用malloc分配的空间之前,要进行清空缓存或赋初值操作。
#include<string.h>memset(ptr,0,MAX_SIZE * sizeof (char));//bzero(ptr,MAX_SIZE * sizeof (char));
memset函数原型
函数的功能:将以s为首地址的大小为n的空间初始化为c
void *memset(void *s, int c, size_t n);//s:要清空的空间的首地址//c:要赋的初始值;一般为0(也可以写为'\0')//n:要清空的空间的大小
bzero函数原型
函数功能:将以s为首地址大小为n的空间初始化为0
void bzero(void *s, size_t n);//s:要清空的空间的首地址//n:要清空的空间的大小
*指针不可以相加,但可以相减
指针 - 指针:两个地址之间相差的数据类型数据的个数
数组
*数组长度不要用变量名来表示,要明确指定或者定义宏
*一维数组
一维数组数组名是指针常量,保存数组首元素的地址
#include<stdio.h>int main(){ int a[MAX_SIZE]; int *p = a; int (*pa)[MAX_SIZE] = &a; //保存一维数组的数组地址的指针:一维数组指针 int i; for(i = 0;i < MAX_SIZE;i++) { scanf("%d",a + i); //scanf("%d",&a[i]); //scanf("%d",p + i); //scanf("%d",p++); //scanf("%d",&p[i]); /*scanf("%d",a++); 错误*/ //scanf("%d",*pa + i); //scanf("%d",&((*pa)[i])); } p = a; for(i = 0;i < MAX_SIZE;i++ ) { printf("%d\n",*(a + 1)); //printf("%d\n",a[i]); //printf("%d\n",*(p + i)); //printf("%d\n",*(p++)); //printf("%d\n",*(*pa + i)); //printf("%d\n",(*pa)[i]); } return 0;}
*二维数组
二维数组数组名是首个一维数组的地址
( ( a + i) + j);
a + i: 第i+1个一维数组的地址
*(a + i): 第i +1个一维数组首元素的地址
*(a + i) +j:第i + 1个一维数组的第j + 1个元素的地址
( (a + i) + j):第i + 1个一维数组的第j + 1个元素的值
*三维数组
三位数组的数组名表示首个二维数组的地址
( ( * (a + i) + j ) + k);
a + i 第i+1个二维数组的地址
*(a + i) 第i + 1个二维数组的首个一维数组的地址
*(a + i) +j 第i + 1个二维数组的第j + 1个一维数组的地址
* ( * (a + i) + j) 第i + 1个二维数组的第j + 1个一维数组的首元素的地址
* ( * (a + i) + j ) + k 第i + 1个二维数组的第j + 1个一维数组的第k + 1个元素的地址
* ( * ( * (a + i) + j ) + k) 第i + 1个二维数组的第j + 1个一维数组的第k + 1个元素的值
*字符数组
#include<stdio.h>int main(){ char src[3][100]; char (*p_src)[3][100]; p_src = &src;//*p_src = src; int i; for(i = 0;i < 3;i++) { scanf("%s",src[i]); //scanf("%s",*(src + i)); //scanf("%s",(*p_src)[i]); } for(i = 0;i < 3;i++) { printf("src = %s\n",src[i]); //printf("src = %s\n",*(src + i)); //printf("src = %s\n",(*p_src)[i]); } return 0;}
*函数传参
传一维数组,用元素指针
传二维数组,用一维数组指针
传三维数组,用二维数组指针
传指针数组,用指针的指针
*一维数组作为形参进行传递时,该数组自动退化为同类型的指针
//传二维数组void printf_src(char (*ptr)[100])//100为步长,不可省略{ int i; for(i = 0;i <3;i++) { printf("%s\n",*(ptr + i)); //ptr + i 即第i+ 1个一维数组的地址 }}
//传指针数组//char *ptr[3];void print_ptr(char **ptr);
#include<stdio.h>int main(){ char *ptr[3] = {"hello1","hello2","hello3"}; //赋值时每个字符串常量的首元素的地址作为字符串的地址,保存在ptr[i]中,且字符串常量保存在数据段的rodata段,不可以被修改 char src[3][100] = {"hello1","hello2","hello3"}; //在占空间中开辟300大小的空间用来存储三个一维数组,此时里面的值可以被修改 int i; //*(ptr[0]) = 'L';运行时报段错误 *(src[0]) = 'L';正确 for(i = 0;i < 3;i++) { printf("%s\n",ptr[i]); } return 0;}
- int a[2][2] = {1,2,3,4};
//书写时可以省略行数(a[][2]),但不可以省略列数
- Linux 第六课
- Linux第六课总结
- linux学习第六课续
- 赶星Linux系列第六课笔记
- 《Linux内核分析》第六课笔记
- linux运维学习第六课
- linux内核第六记
- 嵌入式linux第六章
- linux学习第六天
- Linux初识第六天
- Linux 学习 第六单元
- Linux-第六单元总结
- 第六课
- 第六课
- 实训java第六课 linux的基本命令
- 第六课 linux下进程描述与进程创建
- linux bible 第六章 PCI
- Linux内核探讨-- 第六章
- HDU 5305 Friends(dfs)
- 2.3 uboot源码目录分析
- Android WebView与JavaScript交互详解
- 模式识别中的特征提取及其内在意义
- 自定义Drawable —— 锯齿形
- Linux 第六课
- NOIP 2013 提高组&&队内赛部分题解
- listview分页加载
- Android ORMLite 框架的入门用法
- hdoj--1865 1sting
- Hibernate入门
- CodeForces 589I Lottery
- Handler的三种交互场景
- storm 1.0新功能--Windowing Support in Core Storm滑动窗口