您的位置:首页 > 编程语言 > C语言/C++

C语言学习笔记(十) -指针下 Pointer

2015-03-16 18:50 597 查看
使用指针实现数据交换

//使用指针实现数据交换

#include <stdio.h>
void swap(int  *,int *);

int main(void)
{
    int a,b;
    printf("请输入两个数:\n");
    scanf("%d %d",&a,&b);
    swap(&a,&b);
    printf("交换后的结果为:%d %d\n",a,b);
    return 0;
}
//被调需要传递给主调超过一个值时,将多个值在主调中定义
//将定义的变量地址传递给被调,被调就可以间接访问主调中的多个变量
void swap(int  *const pa,int  *const pb)
{
    int temp;
    temp=*pa;
    *pa=*pb;
    *pb=temp;
}


一维数组名做函数参数

/*

 一维数组名做函数参数

 */

#include <stdio.h>
void output(int *,int);

int main(void)
{
    int a[]={1,2,3,4,5};
    output(a); //实参是地址,1元素的地址
    return 0;
}

//实参是数组首元素地址,形参是接收首元素地址的指针变量
//int p[]这样的写法,仅用来表明实参是数组,[]中有没有数字是没有意义的
void output(int *p,int len)  //int p[]
{
    for (int i=0; i<len; i++) {
        printf("%d ",*(p+i));//=p[i]或p++;
    }
}


二维数组做函数参数

//二维数组做函数参数
  //1.将二维数组降维做函数参数
  //2.使用二维数组名做函数参数

#include <stdio.h>
void output1(int *pa,int row,int col);
void output2(int (*pa)[3],int row,int col);

int main(void)
{
    int a[2][3]={{1,2,3},{4,5,6}};
    output1(a[0],2,3); //降维,实际传输的实参值是int的地址
    output2(a,2,3);//实参是a[0]的地址,实参的类型是int[3]的地址
    return 0;
}

//降维处理
void output1(int *pa,int row,int col)
{
    for (int i=0; i<row; i++) {
        for (int j=0; j<col; j++) {
            printf("%d ",*pa++);
        }
        printf("\n");
    }
}
//形参是能够接收int[3]地址的变量
void output2(int (*pa)[3],int row,int col)
{

    for (int i=0; i<row; i++) {
        for (int j=0; j<col; j++) {
            printf("%d ",*((*pa)+j));
        }
        printf("\n");
        pa++;
    }
}


指针数组

//指针数组
 //指针数组是保存若干指针的数组
 //数组指针是指向数组的指针

#include <stdio.h>
int main(void)
{
    int *p[5];  //定义一个存放5个整型地址的数组
    int a,b,c,d,e;
    p[0]=&a;

    int arr1[2][6]={1,2,3,4,5,6};
    int arr2[4]={11,22,33,44};
    int arr3[1];

    p[0]=arr1[0];
    p[1]=arr1[1];
    p[2]=arr2;
    p[3]=arr3;

    for (int i=0; i<6; i++) {
        printf("%d ",*(p[0]+i));
    }
    printf("\n");
    for (int i=0; i<4; i++) {
        printf("%d ",*(p[2]+i));
    }
    printf("\n");

    //char *p="abc"; "abc"是字符串常量,该字符串的字符不能被修改
    char *pstr[5]={"nihao!","1234","@#$@#$","你好!","@!#"}; //元素 char*
    //通过指针数组交换字符串的值
    int  i=0,j=3;
    if (strcmp(pstr[i],pstr[j])<0) {
        char *t=NULL;
        t=pstr[i];
        pstr[i]=pstr[j];
        pstr[j]=t;
    }
    printf("%s\n%s\n",pstr[i],pstr[j]);
    return 0;
}


指针数组做函数参数

// 指针数组做函数参数
// 指针数组 char * p[10]
       p[0]  char *
       &p[0] char*的地址即为 char **
       char   **app =&p[0]=p
//main的参数,运行时的命令行
//int argc 命令行中传递了几段信息,空格隔开信息
//char*argv[],命令行中的信息字符串

#include <stdio.h>
int main(int argc,char *argv[])
{
    int a[4][4]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};

    char *str=argv[1];
    printf("%s\n",str);
    int num=atoi(str);
    for (int i=0; i<4; i++) {
        printf("%d ",a[num][i]);
    }
    printf("\n");
    //for (int i=0; i<argc; i++) {
    //    printf("%s\n",argv[i]);
    //}
    return 0;
}


函数指针

//函数指针

 //函数指针:指向函数的指针变量
 //函数名 : 表示内存地址,函数指令集合的首地址
 //定义一个指针变量保存函数指令集合的首地址,这个指针变量成为函数指针
 //用处:1.回调函数

#include <stdio.h>
int fun(int);
void sort(int a[],int len,int (*pf)(int [],int,int));
int asc(int a[],int i,int j);
int desc(int a[],int i,int j);
void swap(int a[],int i,int j);
void output();
int main(void)
{
    int (*pf)(int);//pf是函数指针,指向返回值是int,参数是一个int的函数
    pf=&fun;  //取地址符号&可加可不加,将fun函数的首地址赋给pf指针变量

    printf("%d \n",fun(2));//函数调用执行的是地址的跳转
    printf("%d \n",(*pf)(2));
    printf("%d \n",pf(2));//可以写成pf(2)=(*pf)(2)

    int a[]={2,5,8,1,9,3,12,56,21,6};
    sort(a,10,asc);

    for (int i=0; i<10; i++) {
        printf("%d ",a[i]);
    }
    printf("\n");

    sort(a,10,desc);
    for (int i=0; i<10; i++) {
        printf("%d ",a[i]);
    }
    printf("\n");
    return 0;
}

int fun(int i)
{
    printf("call fun\n");
    return i*3;
}

//升序函数
int asc(int a[],int i,int j)
{
    if (a[i]-a[j]>0) {
        return 1;
    }else{
        return 0;
    }
}

//降序函数
int desc(int a[],int i,int j)
{
    if (a[i]-a[j]<0) {
        return 1;
    }else{
        return 0;
    }
}

//排序函数
void sort(int a[],int len,int (*pf)(int [],int,int))
{
    int min=0; //最小值下标位置
    int temp;
    for (int i=0; i<len-1;i++) {
        min=i;
        for (int j=i+1; j<len; j++) {
            if (pf(a,min,j)) {
                min=j;
            }
        }
        temp=a[min];
        a[min]=a[i];
        a[i]=temp;
    }
}

//交换函数
void swap(int a[],int i,int j)
{
    int t;
    t=a[i];
    a[i]=a[j];
    a[j]=t;
}


指针函数

/*
 指针函数

 指针函数:返回值是地址的函数
 void *fun(参数列表)
 返回的地址在主调中也应该是有效的,保证返回的地址时静态存储区或是堆区或是主调栈

 程序内存分布:代码区, 、数据区
 静态存储区     动态存储区
 static  全局  字符串常量     定义开始到到程序结束
 动态存储区
 堆   malloc realloc calloc 调用free结束生命周期
 栈  局部变量和形参        函数结束时结束生命周期

 */

#include <stdio.h>
char * search(char (*p)[20],int num);
int *input();

int main(void)
{
    //char stuname[][20]={"zhangsan","lisi","wangwu","zhaoliu"};
    //char *str=search(stuname,3);

    int *p=input();
    printf("pointer value: \n");
    printf("%d\n",*p);

    return 0;
}

// int arr[]={1,2,3,4,5}; 方式一:全局变量可以返回
// int *input(int arr[]) 主调的栈空间地址可以返回
int *input()
{

    //static int arr[5]={10,2,3,4,5}; //方式二:定义静态数组可以返回
    int  *arr=malloc(5*4);//方式三:动态申请数组可以返回
    return arr;
    //int arr[5]={10,2,3,4,5}; //被调函数的栈空间数组不能返回
}

char * search(char (*p)[20],int num)
{
    //p是第0行整体
    //p+num是第num行
    //*(p+num)是第num行的值

    return *(p+num); //==p[num]
}


野指针

/*

 野指针:指向垃圾的指针
 野指针的种类:
        1.指针变量没有初始化
        2.free之后没有置空
        3.指针越界
 */

//以下是面试题
#include <stdio.h>
void func(char str[]);

int main(void)
{

    char str1[]="hello itany";  //数组
    char *str2="hello itany";   //指针常量
    //strcpy(str1,"abc");
    //strcpy(str2,"abc");  //❌ str2是常量
    //printf("%s \n%s\n",str1,str2);

    char str[]="hello!";
    char *p=str;
    int n=10;
    printf("%lu\n",sizeof(str)); //7
    printf("%lu\n",sizeof(p)); //8   sizeof求得是类型,是整体要有\0
    printf("%lu\n",sizeof(n)); //4

    func();

    return 0;
}


回调函数

/*
  回调函数

  使用回调函数实现排序函数,使之能够处理任何类型的数组
  */

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void sort(int *a,int len, (*p1)(void* ,int,int),(*p2)(void* ,int,int));
int compare(void *a,int i,int j);
void swap(int *a,int i,int j);
void sort (void *a,int len,int size);

int main(void)
{
    int a[]={2,6,4,8,92,4,24};
    sort(a,7,compare,swap);
    sort(a,7,4);
    print();
    return 0;

}


void指针类型

/*

 void指针类型
 定义指针变量时不指定它指向哪一种类型,即它可以通过强制类型转换指向任意一种数据类型

 内存操作:将实参指向的类型忽略,全部按照字节处理
 strcpy
 memcpy(void *dest,void *src,lenth);
 memcmp()
 memset(void *dest,int ch,lenth);
 memset(str,' ',sizeof(str));

 */

#include <stdio.h>
#include <string.h>
int main(void)
{
    int arr1[]={1,2,3,4,5,6};
    int arr2[]={11,22};

    int len1=sizeof(arr1);
    int len2=sizeof(arr2);

    //将arr1拷贝到arr2
    memcpy(arr2,arr1,len1>len2?len2:len1);
    for (int i=0; i<sizeof(arr2)/sizeof(arr2[0]); i++) {
        printf("%d ",arr2[i]);
    }
    printf("\n");

    char str[20]={'\0'};
    memset(str,'*',sizeof(str)-1);
    puts(str);

    //将{1,2,3,4,5,6}变为{1,2,0,0,0,6}
    memset(arr1+2,0,12);//3个字节
    for (int i=0; i<sizeof(arr1)/sizeof(arr1[0]); i++) {
        printf("%d ",arr1[i]);
    }
    printf("\n");

    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: