文档总结19-C语言中的指针

来源:互联网 发布:php 访问粘贴板 编辑:程序博客网 时间:2024/05/22 14:49

一、指针

1.指针

保存地址的,地址是一个数字。
左值代表空间!右值代表空间里面的内容!

1、定义一个指针变量p,类型是int*。
2、p指向一个int型数据
int *p;

指针的绑定
p = &a;

指针的解引用
*p = 23;
int *p1 = &a; //定义指针的同时并且初始

2、const 关键字
const 修饰的变量是常数,不可更改,只能初始化一次

const int a = 23;
a = 1;
//error: assignment of read-only variable ‘a’

const int b;
b = 23;
//error: assignment of read-only variable ‘b’

3、强制类型转换
int * p = (int *)&a;

const 修饰只读变量
const int a = 10;

int arr[a] = {};

//error: variable-sized object may not be initialized

//原因1、const 修饰只读变量.
2、在C++里面对const进行了扩展,表示常量

//宏定义和const?在修饰函数参数时,表示输入型参数。

const与指针,就近原则

int const *p1; //error:assignment of read-only location ‘*p1’

const int *p2; //p2,p2所指向的数据(int) 等同于p1

int * const p3; //野指针,修饰p3,p3不可改变,所指向的内容可改变

const int * const p4; //必须定义时,同时初始化

2.野指针

int *p;

野指针危害:

1、直接指向内核区
2、指向可用也没有别的数据的区域
3、最严重,可用但有别的数据
NULL专用于指针的初始化(写0)

void fun1(int a){    //相当于局部变量,函数调用结束就销毁    printf(“&a = %p\n”, &a);    a = 23;    //不要返回局部变量的地址    return &a;}

函数的输出型参数

void func2(int *p){    printf("p = %p\n",p);    *p = 23;}int main(void){    int a = 11;    printf("&a = %p\n",&a);    //传址调用    func2(&a);    printf("a = %d\n",a);}   

3.传址运算

#include<stdio.h>void swap(int **x, int **y){    int *swap = 0;    swap = *x;    *x = *y;    *y = swap;  }int main(void){    int x = 11, y = 33, *p = &x, *q = &y;    swap(&p,&q);    printf("x = %d y = %d \n", *p, *q);}

4.指针在函数中的应用

int *arr <=> int arr[] <=> int arr[数字]
数组名作为函数参数退化为一个指针
子函数内部改变了原数组里面的内容

5.malloc函数

堆内存也是内存的一种,需要程序员自己手动申请malloc,手动释放
编译器不会自动回收,申请的内存伴随整个程序
流程:申请,判断成功,初始化,使用,释放,指针设置为空
注意:malloc申请的空间,默认是有最小分配的

#include<stdio.h>#include<stdlib.h>#include<string.h>int * shenqing_memory(int num){    int *p = (int *)malloc(num * sizeof(int));    if(NULL == p)    return p;    memset(p, 0, num*sizeof(int));    return p;}void arr_show(int *p, int lenth){    int i = 0;    for(i=0; i<lenth; i++)    printf(" %d",p[i]);    printf("\n");}void set_value(int *p, int lenth){    int i = 0;    for(i=0;i<lenth;i++)    scanf("%d",&p[i]);    printf("\n");}void func_arr(int *p, int lenth){    int i = 0, j = 0, temp = 0;    for(j=0; j<lenth-1; j++)    {        for(i=0;i<lenth-j-1;i++)        {            if(p[i+1] < p[i])            {                temp = p[i+1];                p[i+1] = p[i];                p[i] = temp;            }        }    }    for(i=0;i<lenth;i++)    {           printf(" %d",p[i]);    }    printf("\n");}int main(void){    int num = 0;    int *p = NULL;    printf("请输入数组的个数?");    scanf("%d",&num);/*  p = (int *)malloc(num * sizeof(int));    if(NULL == p)    {        printf("输入错误n");        return -1;    }*/      p = shenqing_memory(num);//  memset(p, 0, num * sizeof(int));    set_value(p,num);    arr_show(p,num);    func_arr(p,num);    if(NULL != p)    {        free(p);        p = NULL;    }}

6.二维数组

二维数组的变量名是首元素首地址{arr[0], arr[1]}
&arr[0]代表第一维数组的首元素首地址
&arr[0][0]代表数组的第二维数组是首元素首地址

#include<stdio.h>int main (void){    int arr[2][3] = {1, 2, 3, 4, 5, 6};    int (*p)[3];    int i = 0, j = 0;    p = arr;        for(i=0; i<2; i++)    {        for(j=0; j<3; j++)        printf("*(*(p+%d)=%d) = %d\n", i, j, *(*(p+i)+j));    }}