C语言单元小结(4)

来源:互联网 发布:乐高机器人编程书 编辑:程序博客网 时间:2024/05/22 12:25

指针

1. 定义一个指针变量p,类型是int* ,指向一个int型的数据
int *p
涉及的指针符号:* &
p = &a;//指针的绑定
*p = 23;//指针的解引用,*p得到了变量(a)

2. 定义指针的同时并且初始化
int *p1 = &a; // == int *p, a; p = &a

3. 指针的运算,就是加减指针所指向的变量类型所占字节大小

同一数组中,两指针相减可得出元素的个数。如果是两个数组的指针相减,将导致未定义的结果

    int arr[5] = {1, 3, 5, 7, 9};    int *p = arr;    int *q = arr+5;//指向9的后一位    int ret=q-p;//元素个数

4.野指针
int *p;
危害:1、直接指向内核区 2、指向可用也没有别的数据的区域 3、可用但有别的数据
//NULL专用于指针的初始化(写0)
int *p = NULL;

6.指针与函数值传递

void fun(int *p)//可以不需要返回值{    *p=1;//直接修改main中变量}int main(void){    int a=0;    fun(&a);//传入地址return 0;}

7.数组指针与函数传递

#include<stdio.h>int func(int *p,int lenth)//传入数组元素个数,保证函数接口明确,可以正确调用{    ...}int main(void){    int arr[3]={1,2,3};    func(arr,3);//数组名作为指针传递}

8.数组内的指针与解引用

#include<stdio.h>int main(void){//知识点//1.*与++有相同的优先级//2.++后置表示,先传递当前值,完成运算之后再++     int arr[]={1,3,5,7,9};     int *p=arr;        *p++;   //*p、p++        *(p++); //p的值给*,p++        //以上两者相同        (*p)++; //*p、*p整体++,即数值++        *++p;        *(++p);//两者相同
#include<stdio.h>int main(void){//3.printf由右向左入值     int arr[]={1,3,5,7,9};     int *p=arr;    printf("(*p)++ = %d *p = %d.\n", (*p)++, *p);    //输出11    printf("*p = %d (*p)++ = %d.\n", *p, (*p)++);    //将输出12} 

9.指针数组

    int arr[5] = {1, 2, 3, 4, 5}, i = 0;    //指针数组,是一个数组,里面的元素是指针    int *p_arr[5];//  p_arr[0] = arr;//指针数组第一个元素存储数组首元素首地址//  p_arr[1] = arr + 1;//指针数组第二个元素存储数组第二个元素地址    //可以写成for循环    for (i=0; i<5; i++)    {        p_arr[i] = arr + i;    }       printf("*p_arr[2] = %d.\n", *p_arr[2]);

9.函数指针
定义一个函数指针, 并且绑定, C语言里对于函数名的绑定有两种方式:
func、&func,通常写成func

void (*p)(void) = &func或func;

调用函数, 指针的解引用

p 、( )或(*p)( )

10.数组指针与普通数组的绑定与解引用

#include <stdio.h>int main(void){    int a[3] = {1,3,5};    int(*p)[3] = a;    //普通数组    printf("sizeof(a)=%d\n", sizeof(a));//12    printf("a=%d\n", a);//a    printf("a+1=%d\n\n",a + 1);//a+4    printf("sizeof(&a)=%d\n", sizeof(&a));//4    printf("&a=%d\n", &a);//a    printf("&a+1=%d\n\n", (&a) + 1);//a+12    //数组指针    printf("sizeof(*p)=%d\n", sizeof(*p));//12    printf("(*p)=%d\n", *p);//9436216    printf("(*p)+1=%d\n\n", (*p) + 1);//9436220    printf("sizeof(p)=%d\n", sizeof(p));//12    printf("p=%d\n", (p));//a    printf("p+1=%d\n\n", (p + 1));//a+12    printf("sizeof(*(*p)=%d\n", sizeof(*(*p)));//4    printf("*(*p)=%d\n", (*(1=%d\n\n", (*(*p))

可以看出,数组指针中的*p相当于普通数组中的数组名a,p相当于普通数组中的&a

这里写图片描述


const

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

#include<stdio.h>int main(void){        const int a=0;//const修饰a,只能初始化一次        a=3;//错误,不可以直接通过a修改内容        int *p=NULL;        p=&a;        *p=2;//正确,可以通过指针更改内容        printf("%d",a);        return 0;}  

const修饰一个指针类型变量

        const int *p;//const修饰*p,p的内容不可更改        int const *p;//同上        int * const p;//const修饰p,p本身不可修改        const int *const p;//const修饰p本身及其内容,均不可改

malloc

堆内存也是内存的一种,需要程序员自己手动申请malloc,手动释放
编译器不会自动回收,申请的内存伴随整个程序

流程:申请,判断成功,初始化,使用,释放,指针设置为空

注意:malloc申请的空间,默认是有最小分配的

If size is 0, then malloc() returns either NULL, or a unique pointer
value that can later be successfully passed to free().
如果长度为0,则返回不是空指针,而是一个可以被成功返回的唯一指针。


typedef

1.typedef int my_int//将int重命名为my_int
2.typedef char * my_char//将char*重命名为my_char
3.typedef (void (*p)(void)) my_func//将void * void 类型的函数重命名为my_func
4.typedef void (*p_arr[10])(void);//函数指针数组:数组里面的元素都是指针(函数指针)


二维数组

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

int arr[2][3] = {1, 2, 3, 4, 5, 6};
arr代表数组首元素首地址(&arr[0])

&arr[0]代表第一维数组的首元素首地址
&arr[0][0]代表数组的第二维数组是首元素首地址

    int arr[2][3] = {1, 2, 3, 4, 5, 6};     int (*p)[3];//数组指针, 指针指向了一个int[3]类型的数据结构    p = arr;    //指针方式遍历二维数组    int i = 0, j = 0;    for (i=0; i<2; i++)    {        for (j=0; j<3; j++)        printf("*(*(p+%d)+%d) = %d.\n", i, j, *(*(p+i)+j));    }

实现:

利用传值调用实现swap功能
这里写图片描述

利用malloc申请动态数组,完成排序
这里写图片描述
这里写图片描述

原创粉丝点击