这是指针的一些小问题
我一般的理解知识点的思路:
1.格式(如何输入输出,这种方式有什么用)
2.用自己会基础知识往里面套
3.看大佬的博客看看大哥们是怎么用简单方法
其实指针和平常的差不多(菜鸡理解),就是一个指向的地址,一个指向的地址中的数值。(但是大家还是不太理解*p)
理论知识我就不点了直接上题型:
指针我分了板块
- 简单的指针输入输出
- 数组指针
- 函数指针
- 字符串指针
- 动态分配
1.简单的指针输入输出
//(一般区分的话我是以*p为数值而p为地址)
两种定义方法:
1.int a;
int *p=&a;
2.int a;
int *p;
p = &a;(因为int *这个一个整体)码片
3.&(*P)还是个地址
4.*(&(*p))还是个指针(3.4可以套娃)
2. 数组指针
定义:int *p;(p=&a[0]//p = a;)这两个用那个都行
#include <stdio.h>
int main()
{
int a[10]={1,2,3,4,5,6,7};
int *p;
p = a;
for(int i = 0; i<3;i++)
{
p = p+i;
}
printf("%d",*p);//printf("%d",*a);
}//这个注意的点:这个 p = p+i;最后的值是多少就是多少,并不是说p加了i还能加
//*p已经指到了a所以printf的时候可以*a
下面也是一个小重点:指针指回去
#include <stdio.h>//输出数组的
int main()
{
int a[10];
int *p;
p = a;
for(int i = 0 ;i < 3;i++)
{
scanf("%d",p++);
}
p =a;//**指针还有整回去,否则指针还是指向最后赋值的地方**
for(int i = 0 ;i < 3;p++,i++)
{
printf("%d ",*p);
}
}
这里就是一些简单的输入输出,但是比较细节的点!!!
3.函数指针
这是不用指针的代码先可以参考一下,然后比较他们之间的差距(这就是我说的第二种做题方法)
#include<stdio.h>
#include<math.h>
int str (int n);
int main()
{
int m,b;
scanf("%d",&m);
b = str(m);
printf("result = %d",b);
return 0;
}
int str (int n)
{
int sum=0;
int i;
for( i = 1; i<=n;i++)
{
sum = sum + pow(2,i);
}
return sum;
}
这个是用指针的
#include<stdio.h>
#include<math.h>
int str (int n);//定义函数
int main()
{
int m,b;
int (*p)(int n);//定义指针(仿照着你定义的函数)
scanf("%d",&m);
p = str;//把函数str赋值给指针变量p,让p指向str函数
b = (*p)(m);//括号需要加
printf("result = %d",b);
return 0;
}
int str (int n)
{
int sum=0;
int i;
for( i = 1; i<=n;i++)
{
sum = sum + pow(2,i);
}
return sum;
}
我们发现:1.定义指针2.赋值给地址3.(*p)需要加括号
4.字符串指针
小可爱们忍一忍马上就完了,(●ˇ∀ˇ●) 对于字符串指针爽爽子在此说一下
字符串有:比较大小(strcmp),复制(strcpy),连接(strcat)字符串长度(strlen)
基本上复制时候用指针就可,其他的爽爽子感觉都挺难的,估计是太菜的缘故。
但是为什么复制能用指针简单表示呢?(复制的话直接就是字符串的本身,没有拆分字符串,指针指向字符串以后就相当于换墨水交换地址就行)
`
用指针代替strcmp
#include <stdio.h>
int main()
{
char a[]="I am a b.",b[]="I am a g.",c[20],*p1,*p2,*p3;
p1=a;
p2=b;
p3=c;//先给地址
for( ;*p1!='\0' ;p1++,p2++,p3++)
{
*p3 = *p2;//3b2b1g
*p2 = *p1;//3b2g1g
*p1 = *p3;//3b2g1b
//赋值直接换
}
*p1= '\0';
*p2= '\0';
*p3= '\0';//字符数组的结束语 (一定要有)
printf("string a is:%s\n",a);
printf("string b is:%s\n",b);
return 0;
}//这个题就是换墨水的问题交换一下
用指针来比较字符串的大小
比较大小需要用到(1.比较2.排序)
大家一看到排序是不是有感觉自己不行了?你kin你kin你擦
#include <stdio.h>
#include <string.h>
int main()
{void sort(char *name[],int n);
void print(char *name[],int n);//用指针来定义,并让指针指向字符串
char *name[]={"Follow","Great","FORTRAN","Computer"};
int n=4;
sort(name,n);
print(name,n);
return 0;
}
void sort(char *name[],int n)
{
char *temp; //因为指向的都是地址所以要再次定义一个指针(就相当于用int全用int)
int i,j,k;
for (i=0;i<n-1;i++)
{ k=i;
for (j=0;j<n-i-1;j++)
if(strcmp(name[k],name[j])>0) k=j;
if (k!=i)//如果一样的比较没必要
{
temp=name[i];
name[i]=name[k];
name[k]=temp;//换墨水的升级版=排序
}
}
}
void print(char *name[ ],int n)
{ int i;
for(i=0;i<n;i++)
printf("%s\n",name[i]);
}
嘤嘤嘤,好好看一看你能懂的
对于字符数组的赋值也有陷阱
#include <stdio.h>
int main()
{
char a[14]="asda";
puts(a);
}//对
#include <stdio.h>
int main()
{
char a[14];
a[14]="asda";
puts(a);
}
//不对
第二个代码应改成
#include <stdio.h>
int main()
{
char *a;
a="asda";
puts(a);
}//直接就可以输入输出不有写a【14】这种
一个个的是表示不出来,但是都对号入座了。
关于指向地址的地址选择应该会考的(看到这里的人毕竟是少数,嘿嘿)
实在不会就画画图
5.动态分配
动态内存的好处:用时分配,不用释放!(好处大大滴)
#include<stdio.h>
#include<stdlib.h>
int main()
{
double a[1000];
int n ;
double *p,sum = 0;
double max,min;
scanf("%d",&n);
if((p=(double*)calloc(n,sizeof(double)))==NULL){
exit(1);//动态分配
}
for(int i = 0;i < n;i++)
{
scanf("%lf",p+i);
if(min>*(p+i))
min = *(p+i);
if(max<*(p+i))
max = *(p+i);
}
free(p);//释放空间
printf("max = %.0lf\n",max);
printf("min = %.0lf\n",min);
return 0;
}