十四、void*  万能指针

void可以做函数的返回值,

从来没有出现过void a;原因是void是空类型,编译器并不知道给a开辟多大的空间。

void* 可以做函数的返回值、函数的参数。

void* 作为函数的参数的时候,可以接收任意类型指针

  • void* 主要用来保存内存的地址。
  • 其他任意类型的指针给void* 赋值或者参数传递,不需要额外的操作,直接赋值或传递参数。
  • 当需要把void* 转换为其他类型指针的时候,需要强制类型转换后,才可以使用。因为void* 中只保留的地址,不知道如何对数据进行访问。如果没有转换,*p (解引用)、p+1(挪到下一个元素)都会失败,void没说开多大的空间,没有void 类型的变量。
  • void* ,做函数的返回值,做函数的参数。
void指针典型的用法

void* my_memcpy(void* dst,void* src,int size)   //size是src的总字节数
{
    char* pdst=(char*)dst;
    char* psrc=(char*)src;

    int i=0;
    for(i=0;i<size;i++)
    {
        *pdst=*psrc;
        pdst++;
        psrc++;
    }
    return dst;
}

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void* my_memcpy(void* dst,void* src,int size)   //size是src的总字节数
{
	char* pdst=(char*)dst;
	char* psrc=(char*)src;

	int i=0;
	for(i=0;i<size;i++)
	{
		*pdst=*psrc;
		pdst++;
		psrc++;
	}
	return dst;
}
int main()
{
	double d1[5]={1.11,2.22,3.33,4.44,5.55};
	double d2[5]={0};

	my_memcpy(d2,d1,sizeof(d1));  //8*5=40

	int i=0;
	for(i=0;i<5;i++)
	{
		printf("%lf\n",d2[i]);
	}
	return 0;
}

十五、指针数组

指针数组的定义

类型* [ 常量表达式] = {NULL};指针不确定,先指到空,之后找到相应的位置。

指针数组,数组中存储的元素是指针类型

char* arg1[10]={NULL};   常用,这里装了10个指针

int* arg2[10];

char* arg[5]={"hello","worlg","ok","fine","end"};

arg是一个数组,里面存储了5个地址

每个指针都存储了字符常量的地址,每个指针不能改变指向的内容,指针自己可以走,指针可以指向其他位置。

char str[100]={0};

arg[0]=str;

那么arg[0]和str这个字符数组进行了关联,

如果执行strcpy(arg[0],“hello“),那么相当于给str,写入“hello”,arg[0]中存储的是数组(str)的地址。

示例
#include <stdio.h>
#include <string.h>
int main()
{
	char* arg[5]={"hello","world","ok","fine","end"};
	int i=0;
	for(i=0;i<5;i++)
	{
		printf("%d %s\n",i,arg[i]);
	}

	arg[0]="aaa";  //这里是赋值
	for(i=0;i<5;i++)
	{
		printf("%d %s\n",i,arg[i]);
	}

	char str1[100]={0};
	arg[0]=str1;
	strcpy(arg[0],"bbb"); // 这里是函数的的调用,如果不开辟一个新空间,原来的“hello”是一个字符串常量,无法修改。
	for(i=0;i<5;i++)
	{
		printf("%d %s\n",i,arg[i]);
	}

	char* p="hello";
	char str2[100]={0};
	p=str2;
	strcpy(p,"ccc");

	return 0;
}
#include <stdio.h>
int main()
{
	char str[100]="how are you";
	char* arg[3]={NULL};

	char* tmp=str;
	arg[0]=str;
	int i=1;
	while(*tmp && i<3)
	{
		if(' '==*tmp)
		{
			arg[i]=tmp+1;
			*tmp='\0';
			i++;
		}
		tmp++;
	}
	for(i=0;i<3;i++)
	{
		printf("%d %s\n",i,arg[i]);
	}
	return 0;
}
指针数组的传参

char* pstr[ ]  和  char** pstr 表达的含义是一样的

#include <stdio.h>

void show1(char* pstr[],int size)
{
	int i=0;
	for(i=0;i<size;i++)
	{
		printf("%d %s\n",i,pstr[i]);
	}
}

void show2(char** pstr,int size)
{
	int i=0;
	for(i=0;i<size;i++)
	{
		//printf("%d %s\n",i,pstr[i]);
		printf("%d %s\n",i,*(pstr+i));
	}
}
int main()
{
	char* str1[]={"hello","aaa","bbb"};
	show1(str1,3);
	show2(str1,3);
	return 0;
}

十六、数组指针

应用:函数需要传递二维数组的时候,会使用数组指针,在被调函数中,数组的内容可读可写

1、数组指针

主语是指针,指针往哪里指?指向谁?

数组指针本质是指针,指向二维数组当中的某一行,一般来说是起始位置,存储的是一个数组的地址,一般和二维数组搭配使用。

&a(取地址a)  int(*)  [5]  数组指针,获得整个一维数组

int a[5]={1,2,3,4,5};

  • 对一维数组进行取地址 & 操作:&a[0],&a,a 地址不变。a是变量,&a不能看做二级指针,&a叫做数组指针,表示的是整个一维数组,&a+1 偏移量:5*sizeof(int)=20
  • 对数组指针执行解引用 * 操作,&a地址值不变(都是&a[0]的地址)   *&a  == a;表示的是数组中的一个变量的地址  sizeof(int)=4
int * 和 int[ ]的区别

sizeof(*int)==8;

sizeof(int[ ])=sizeof(int) * 元素的个数;

&取地址
  • int*----->    int**  二级指针
  • int[]---> int(*)[3]   数组指针

#include <stdio.h>

int main()
{
	int a[5]={1,2,3,4,5};
	printf("&a[0] %p\n",&a[0]);
	printf("&a[1] %p\n",&a[1]);
	printf("&a[2] %p\n",&a[2]);


    printf("a %p \n",a);  // int* = int[]
    printf("a+1 %p \n",a+1);
    printf("a+3 %p \n",a+3);

    printf("a[0] %d \n",a[0]);
    printf("a[1] %d \n",a[1]);
    printf("a[3] %d \n",a[3]);

    // &a int (*)[5] 数组指针 ,获得整个一维数组
    printf("&a %p\n",&a); //&a =  int(*)[5]
    printf("&a+1 %p\n",&a+1);

	int (*p)[5]=&a;

    printf("  *&a %p \n",*&a);
    printf(" *&(a+1)%p \n", *(&a+1));

    printf("a[0] %d\n",p[0][0]);
    printf("a[0] %d\n",*((*(p+0))+0));
	return 0;
}
2、二维数组和数组指针
二维数组的传参
#include <stdio.h>
void show(int (*p)[2],int line ,int col )
{

    int i = 0 ;
    int j = 0 ;
    for(j=0;j<line;j++)
    {
        for(i=0;i<col;i++)
        {
           // printf("%d\n",p[j][i]);
            printf("%d\n",*(*(p+j)+i));
        }
    }
}
int main()
{
    int a[3][2]={1,2,3,4,5,6};

    show(a,3,2);
    return 0;
}

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐