嵌入式学习笔记十三——C语言指针变量、一维数组的指针、快速排序

指针变量

指针初始化

指针变量初始化:如果没有初始化,指针是随机值,既野指针。初始化可以让指针变量有明确的指向。

	int a = 10;
	int *p = &a;//指针初始化
	
	int *p = NULL; //NULL 0号地址   --- 空指针 

指针赋值

	int * p;
	p = NULL;
	
	int a;
	int *p;
	p = &a;
	
	int *p,q; //p是指针类型 int * 
	          //q是int型
    int *p,*q; //此时表示定义了两个 int*类型的变量 p 和q 
	           //注意:  
			   //定义时候的 * 修饰变量名的 表示定义的是一个指针类型的变量 

为什么需要地址?

    为了实现被调修改主调函数,值传递无法改变主函数中的数据,如果要对数据进行修改,就要用到指针进行地址传递。

指针作为函数的参数

形参:指针类型变量,用来接收实参,实参是要操作的内存空间的地址。

实参:需要修改的变量的地址,被调函数1中一定要有*运算

体会指针,被调修改主调,练习:1.找出两个数中最大值 和 最小值写成函数 2.写swap()函数,实现交换两数的值。     

#include <stdio.h>
void add(int n,int m,int *sum)
{
	*sum = n + m;
}
void findMaxMin(int n,int m,int *max,int *min)
{
	if(n>m)
	{
		*max = n;
		*min = m;
	}
	else 
	{
		*max = m;
		*min = n;
	}
}
void Swap(int *a,int *b)
{
	int t = *a;
	*a = *b;
	*b = t;
}
int main(void)
{
	int x=5,y=10;
	int sum;
	int max;
	int min;
//	add(x,y,&sum);
//	printf("%d\n",sum);
//	findMaxMin(x,y,&max,&min);
//  printf("max = %d\nmin = %d\n",max,min);
    Swap(&x,&y);
	printf("x = %d\ny = %d\n",x,y);
	return 0;
}

形参中的指针类型变量,只需定义需要修改的变量就可以,其他的值如果也用地址来操作就有些多于了,效率也会降低。需要修改的数据,在传入实参时要用取地址&来传入地址。

指针和一维整型数组

int  a[5]; 数组名a表示数组首元素的地址,数组名是个常量不能自增自减。

a =>&a[0]   a[0]的数据类型是int,&a[0]的数据类型是int*(指针类型)

int *p = a; p指向数组a

指针运算:&取地址,*指针运算(访问运算对象指向的地址)

p+1,p+n,p-1,p-n,p++,p--:表示(+向后,-向前)跳过了一个或n个基类型。

对数组指针进行自加减:

//打印数组
void printArray(int *a,int len)
{
	int i = 0;
	for (i = 0;i < len ;++i)
	{
		printf ("a[%d] = %d\n",i,*a++);
	//	printf ("a[%d] = %d\n",i,a[i]);
	//	printf ("a[%d] = %d\n",i,i[a]);
	//	printf ("a[%d] = %d\n",i,*(a+i));
	}
}

1. a <=>  &a[0]//a[0]的数据类型 -- int型 ,&a[0]  地址的类型 -- int* 

int *p = a; //表示 p指向数组a

此时*p等价于a[0],*p 访问指针p指向的地址中的内容。*p  <=> a[0]

2.*(p+i) <=> a[i] <=> *(a+i)//a是一个地址,代表首元素首地址,所以a = & a[0]  <=> p
 a[i]  <=> *(a+i)
 i[a]  <=> *(i+a) //a[i]==i[a];

所以上述代码中所有printf打印的内容都相同。

3.如果p,q,都是地址,则:

p - q     //表示差了多少元素(基类型)

两指针相减,必须是同一类型的指针  
          
p + q     是不允许的,会报错,没有意义。 

用指针可以实现用迭代的方式实现逆序,排序和查找。

练习:

1. 准备一个数组,找数组中的最大值 ,用指针完成。

2.数组逆序。

3.对数组排序。
 下面的代码只要修改主函数就能实现相关功能。

void findMax(int *a,int len)//找最大值
{
	int i = 0;
	 int max = *a;
	for (i = 0;i < len;++i)
	{
		if (*(a+i)>max)
			max = *(a+i);
	}
     return max;
}

void printArray2(int *begin,int *end)//打印
{
	while (begin <= end)
		printf("%d ",*begin++);
	putchar('\n');
}

void revArray(int *begin,int *end)//数组逆序
{
	int t;
	while(begin < end)//不用等于
	{
		t = *begin;
		*begin=*end;
		*end = t;
		++begin;
		--end;
	}
}
void selectSort(int *begin,int *end)//选择排序
{
	int *p;
	int *q;
	for (p = begin;p < end;++p)
	{
		for (q = p+1;q <= end;++q)
			if (*q < *p)
				Swap(q,p);
	}
}

void bubbleSort(int *begin,int *end)//冒泡排序
{
	int *p;
	int *q;
	for (p = end;p >begin;--p)
	{
		for (q = begin;q < p;++q)
		{
			if (*q > *(q+1))
				Swap(q,q+1);
		}
	}

}
void insertSort(int *begin,int *end)//插入排序
{
	int *p;
	int *q;
	for (p = begin+1;p <= end;++p)
	{
		int t = *p;
		q = p;
		while (q > begin && t < *(q-1))
		{
			*q = *(q -1);
			--q;
		}
		*q = t;
	}
}

int * binaryFind(int *begin,int *end,int n)//二分查找
{
	int *ret = NULL;
	int *mid;
	while (begin <= end)
	{
		mid = begin + (end - begin)/2;
		if(*mid < n)
			end = mid - 1;
		else if (*mid > n)
			begin = mid +1;
		else
		{
			ret = mid;
			break;
		}
	}
    return ret;

}

int main(void)
{
	int a[] = {1,5,7,8,4,1,3};
	int len = sizeof(a)/sizeof(a[0]);
//    printArray2(a,a+len-1);
    int max = 0;
	findMax(a,5,&max);
	printf("max = %d\n",max);
	insertSort(a,a+len-1);
//	revArray(a,a+len-1);
	int n;
	scanf("%d",&n);
	printArray2(a,a+len-1);
	return 0;
}


快速排序

思想:使用分治法的策略来把一个序列分为较小和较大的两个子序列,然后递归地排序两个子序列。快速排序的基本思想可以概括为以下几个步骤:

1.选择基准值:从数组中选择一个元素作为基准值(pivot),通常选择第一个元素、最后一个元素或中间元素。

2.分区操作:重新排列数组,使得所有比基准值小的元素都在基准值的左边,所有比基准值大的元素都在基准值的右边。这个称为分区(partitioning)的过程。

3.递归排序:递归地将上述步骤应用到基准值左边和右边的子数组上。

4.结束条件:当子数组的大小减少到1或0时,递归结束。

理解过程:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值