C语言Day12(c程序设计小红书+pta)

目录

(一)用指针交换两个变量的值

(二)指针:

(三)两个整数从大到小输出

(四)通过指针指向数组元素

 (五)通过指针访问(输出)数组中的所有元素

(六)用指针实现数组的反序

(七)选择法排序 

(八)用指针指向多维数组

(九)输出二维数组所有元素的值

(十)const:不允许修改(其修饰的)内容

(十一)指向函数的指针

(十二)动态内存


 

(一)用指针交换两个变量的值

#include<stdio.h>
void swap(int* a, int* b)
{
	int temp;
	temp= *a;
	*a = *b;
	*b = temp;
}
int main()
{
	int a, b;
	scanf("%d %d", &a, &b);
	printf("交换前:%d,%d", a, b);
	swap(&a, &b);
	printf("交换后:%d,%d", a, b);
	return 0;
}

(二)指针:

一个函数A通过调用函数B,来达到修改A中变量的值,必须传指针,在B中必须解引用。

int *p;
*p=10;

这是错误的,这个p是悬空指针,悬挂指针,野指针,并没有指向一个有效的地址。

 p是指向一个变量的变量,所以一定要先指向一个变量,给那个变量赋值,才可以。

解一元二次方程时如果有两个根,要改变函数的定义,因为在C语言中只能返回一个或者0个值。

但是注意数组返回可以返回两个,一个是数组名,一个是数组长度。

char atr1[]="hello world";(是字符串数组,是字符串)

char *str2="hello world";(是字符串常量)

Hello world 需要十二个字节的空间,而指针只占四个字节,所以Hello world在指针里面是常量

str1[0]='x';(数组中每一个元素都可以被修改)

str2[0]='x';(会报错,运行崩溃)

#include<stdio.h>
#include<math.h>

int Fun(int a, int b, int c,double* x1, double* x2)
/*x1,x2称为输出函数,传递的是指针,在内部解引用,所以可以传出去*/
{
	int d = b * b - 4 * a * c;
	*x1 = (-b + sqrt(d)) / (2 * a);
	*x2= (-b -sqrt(d)) / (2 * a);
	return 2;/*因为只能返回0个或者1个值,所以我们在这里返回根的个数*/
}
int main()
{
	double x1;
	double x2;
	Fun(1, -3, 2, &x1, &x2);
	printf("%.2lf,%.2lf\n", x1, x2);
	return 0;
}

(三)两个整数从大到小输出

#include<stdio.h>
#include<math.h>
void max(int* a, int* b)
{
	if (*a < *b)
	{
		int temp;
		temp = *a;
		*a = *b;
		*b = temp;
	}
}
int main()
{
	int a, b;
	scanf("%d %d", &a, &b);
	max(&a, &b);
	printf("%d,%d", a, b);
	return 0;
}

(四)通过指针指向数组元素

定义的时候是*p=&a(万万注意)

一维数组arr的名字表示整个数组得到情况:

1.在定义数组的同一个函数中求sizeof。sizeof(arr)

2.在定义数组的同一个函数中,&arr+1表示加整个数组的大小。

int arr[10].&arr与&arr+1相差40个字节。

其他情况arr表示数组首地址。

int main()
{
	int arr[10] = { 1,3,5,7,9,11,13,15,17,19 };
	int* p = &arr[0];/*与int* p = arr;等价*/
	/*int* p = arr;*/
	printf("%d,%d\n", arr[0], *p);/*注意观察这两个是等价的*/
	printf("%d\n", sizeof(arr));/*此句告诉我们arr可以代表整个数组,在这种情况下*/
	printf("%d,%d\n", &arr, &arr + 1);
	/*&arr与 &arr + 1相差四十个字节(也就是整个数组所占的字节)*/
	return 0;
}

 (五)通过指针访问(输出)数组中的所有元素

for (int i = 0; i < 10; i++)
{
	printf("%d ", *p);
	p++;
}

指针可以++,意思是加一个单元格

for (int i = 0; i < 10; i++)
{
	printf("%d ", *p++);
}
for (int i = 0; i < 10; i++)
{
	printf("%d ", *(p+i));
}

指针的算术运算:前提是指针指向一个数组,保证程序不越界。

p+整数,p++,++p,p--,--p,p-i

int main()
{
	int arr[10] = { 1,3,5,7,9,11,13,15,17,19 };
	int* p = &arr[9];
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", *p);
		p--;
	}
	return 0;
}

这个程序实现了数组的反序。

for (int i = 0; i < 10; i++)
{
	printf("%d ", *(p-i));
}

指针的关系运算:>,<,>=,<=,==,!=

for (int *p=arr;p!=&arr[10];p++)
{
	printf("%d ", *p);
}

数组作为参数传递:数组仅仅表示数组首元素的地址。

传数组名和数组的长度。

#include<stdio.h>
void show(int* p, int n)
{
	for (int i = 0; i < n; i++)
		printf("%d ", p[i]);
	printf("\n");
}
int main()
{
	int arr[10] = { 1,3,5,7,9,11,13,15,17,19 };
	show(arr, sizeof(arr) / sizeof(arr[0]));
	return 0;
}

(六)用指针实现数组的反序

#include<stdio.h>
void show(int* p, int n)
{
	for (int i = n-1; i>=0; i--)
		printf("%d ", p[i]);
	printf("\n");
}
int main()
{
	int arr[10] = { 1,3,5,7,9,11,13,15,17,19 };
	show(arr, sizeof(arr) / sizeof(arr[0]));
	return 0;
}
void show(int* p, int n)
{
	int temp;
	for (int i = 0, j = n - 1; i < j; i++, j--)
	{
		temp = p[i];
		p[i] = p[j];
		p[j] = temp;
	}
}
int main()
{
	int arr[10] = { 1,3,5,7,9,11,13,15,17,19 };
	show(arr, sizeof(arr) / sizeof(arr[0]));
	for (int i = 0; i < 10; i++)
		printf("%d ", arr[i]);
	return 0;
}
for (int i = 0, j = n - 1; i < j; i++, j--)
{
	temp = *(p+i);
	*(p + i) = *(p+j);
	*(p + j) = temp;
}

(七)选择法排序 

#include<stdio.h>
#include<math.h>
void paixu(int* p, int n)
{
	int temp;
	int min;
	for (int i = 0; i<n-1;i++)
	{
		min = i;
		for (int j = i + 1; j < n; j++)
		{
			if (p[min] > p[j])
			{
				min = j;
			}
		}
		temp = p[min];
		p[min] = p[i];
		p[i] = temp;
	}
}
int main()
{
	int arr[10] = { 1,9,5,3,2,4,6,8,7,0};
	paixu(arr, sizeof(arr) / sizeof(arr[0]));
	for (int i = 0; i < 10; i++)
		printf("%d ", arr[i]);
	return 0;
}

用指针的话就是把数组改成指针。

(八)用指针指向多维数组

类型类型
                        int arr[4]                 int brr[3][4]
arrint*x;brrint(*x)[4]
首元素的地址相当于第一行的地址,把每一行看做一个元素
arr+1int*x;brr[0]int*x;
相当于第一行的元素地址,也就是一维数组的地址,和arr差不多
arr[0]int x;brr+1int(*x)[4]
brr[0]+1int*x;
brr[0][0]int
brr[0][0]+1int

(九)输出二维数组所有元素的值

#include<stdio.h>
#include<math.h>
void show(int(*brr)[4], int row)/*注意注意注意多维数组的指针怎么表示*/
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < 4; j++)
		{
			printf("%4d", brr[i][j]);
		}
		printf("\n");
	}
}
int main()
{
	int arr[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
	show(arr, 3);
	return 0;
}

(十)const:不允许修改(其修饰的)内容

const a=10;

a=20;

这样是不对的,因为const已经把a的值固定住了,不能再把20赋值给她了。

基本类型对于const是透明的,const int a与int const a是等同的。

const只能修饰直接右边。

const int*p=&a;

*p就不能再变了,但是p的值可以变。

p=&b;这句话是可以的不会报错。

int *const p1=&c;

p1的值不能再变了,*p1就可以再变。

*p1=d;是可以的。00.

字符串和普通数组的区别:字符串可以通过‘\0’判断结尾,不需要传递长度

(十一)指向函数的指针

函数族

标准规定函数名也表示函数的入口地址。

int (*pfun)(int,int);

pfun一定是指针,该指针指向函数,函数参数为int,int,返回值为int,即pfun是一个函数指针

int max(int a,int b)

{

return a>=b?a:b;

}

.......

int main()

{

int (*pfun)(int,int);

pfun=max;或者pfun=&max;

...
}

(十二)动态内存

局部变量:分配的内存区域在栈,很小

动态内存使用的场景:

1.需要大容量内存2.在一个函数创建的内存在别的函数中还需要使用时

void:没有,可以修饰返回值和参数列表。

void*:没有类型信息的指针,这个指针仅仅是记录地址。

如何创建动态内存:

malloc:创建内存,需要引用<stdlib.h>,失败返回NULL,成功返回地址。

calloc:创建内存

realloc:创建内存

free:释放内存

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值