C语言指针

来源:互联网 发布:合同管理数据库 编辑:程序博客网 时间:2024/06/15 22:34

一、指针

1.为什么使用指针

目的:对地址进行操作(java和c#看不到指针,指针给包装起来了)

2.指针的本质

指针就是一个变量,但是跟普通的变量又有所区别,指针变量保存的是另外一个变量的地址,而普通变量保存的就是具体的值。

3.既然指针是变量,也具有变量的一些特性。

①类型

②定义

③初始化

④赋值

⑤其它一些运算操作

4.定义

格式:类型名 *指针变量的名字      //int *p;定义了一个整型变量指针

类型名的作用:因为指针保存的是地址,就得知道对地址进行操作的时候去多大的字节

二、指针和数组的区别

1.数组名是地址常量,指针是变量;

2.数组是静态分配内存空间,指针是动态分配内存空间;

   数组扩展性大,利用率低,容易造成浪费,指针相反;

3.数组是直接访问内存,指针是间接访问内存;

   数组使用不灵活,但比较安全,若使用不当可能会造成溢出

   指针使用灵活,但不安全,使用不当会造成内存泄漏或段错误

4.char *str[] = "hello";  //保存在.text;

5.数组名作为函数参数,退化为指针处理

三、指针和字符串

字符串在C语言中主要有两种处理方式

1.通过字符数组

2.通过字符指针变量指向这个字符串

char *str = "hello"; //不是吧hello赋值给str,而是将str初始化为hello的首地址,保存在.text

分析:
首先把hello保存在.text段,然后把hello的首地址赋给str

分配的内存

1. .text段分配空间保存hello//6

2. 分配栈空间保存局部变量str//4

            需要分配的空间6+4=10个字节

    c语言没有字符串这个变量,java里有

    c语言中字符串的本质:指针指向头,固定尾部的地址相连的一段内存,在内存中是多个字节连续分布构成。

三个核心要点:

1.指针指向头、首地址

2.固定尾部'\0'

3.各个字符地址是相连的

魔数:在c语言用来表示特定含义的负号:'\0'

幻数:让人产生幻想的数

for( i = 0 ; i < 5 ; i++ ); //5就是幻数

四、指针和函数

1.指针指向函数:函数指针

定义一个函数时,也会给该函数分配地址!调用函数时,可以理解为发生了一次中断!调用函数时,也是需要进行中断类似的操作:保存现场、给形参分配栈空间、移动指针等;

函数地址:函数名。

函数指针:左右法则:int (*p)( int ,int );

使用:

int add( int a , int b)

{

return a + b;

}

int main()

{

int (*p)( int , int )//定义函数指针

p = add;

int result = (*p)(a,b);//调用

}

函数指针的作用:主要是为了可以用函数指针来调用不同的函数

2.函数的参数是指针变量

3.函数的返回值是指针

五、二级指针

int a = 12;

int *p = &a;

int **p = &p; //二级指针

六、野指针和段错误

野指针:指针变量指向了不确定的地址空间,或者指向了一个确定的地址空间(但没有权限),导致引用空间的结果不可预知

野指针危害

1.导致段错误!段错误是地址错误,系统主动保存

2.没有结果,(后果贼可怕,一定要避免)

3.发生连环错误,错误循环叠加,你都不知道他到底叠加到了什么地方

原因:

1.使用前没有初始化或者没有指向空间;

2.不清楚某些地址空间的访问权限,识图修改这些空间的值

如:0地址:受系统保护,无操作权限。

char *p = “linux”;

*(p+1) = 'w';

3.有权限,但超过了这个权限,访问空间是,内存越界导致野指针,进而导致段错误

如:int buf[4] = {1,2,3,4};

*(buf + 5) = 10;

避免:

1.养成良好习惯,定义指针变量初始化

int *p = NULL;//即使以后有段错误,系统也会报警

2.使用之前,一定要对指针变量初始化或者指向一个确定的空间

3.使用前检查指针是否为空

★#define 和 typedef

共同点:都可以对数据类型进行重命名

区别:

1.#define 是在预处理的时候进行替换的,typedef不是

2.#define dINT int* //#define只是简单的替换

    typedef int* tINT;//

dINT a,b; //等价于int *a,b;

tINT a,b; //等价于int *a,*b;

3.#define可以自由组合,typedef不行

#define dINT int

typedef int tINT

usigned dint a;//可行

usigned tint a;//不可行

4.typedef可以组建新的类型

typedef struct node

{

int a;

int b;

}