原创 C语言指针(上篇)

2012-6-19 21:46 1136 9 10 分类: MCU/ 嵌入式

最近总结再学习了下C语言和指针,现在总结整理成笔记,方便以后学习提高,有什么错误的地方同时也欢迎网友提出批评,共同学习进步!

/******************************************************************************************
         关于谭浩强C语言指针部分的例题练习

定义   含    义
int i;   定义整型变量i
int *p   p为指向整型数据的指针变量
int a[n];  定义整型数组a,它有n个元素
int *p[n];  定义指针数组p,它由n个指向整型数据的指针元素组成
int (*p)[n]; p为指向含n个元素的一维数组的指针变量
int f();  f为带回整型函数值的函数
int *p();  p为带回一个指针的函数,该指针指向整型数据
int (*p)();  p为指向函数的指针,该函数返回一个整型值
int **p;  P是一个指针变量,它指向一个指向整型数据的指针变量


//------------------------------------------------------------------------------------------

函数的形参和实参具有以下特点:
1. 形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。
 因此,形参只有在函数内部有效。函数调用结束返回主调函数后则不能再使用该形参变量。
2. 实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,
 它们都必须具有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使实参获得确定值。
3. 实参和形参在数量上,类型上,顺序上应严格一致,否则会发生类型不匹配"的错误。
4. 函数调用中发生的数据传送是单向的。即只能把实参的值传送给形参,而不能把形参的值反向地传送给实参。
  因此在函数调用过程中,形参的值发生改变,而实参中的值不会变化。


//------------------------------------------------------------------------------------------
用数组名作函数参数与用数组元素作实参有几点不同:

1) 用数组元素作实参时,只要数组类型和函数的形参变量的类型一致,
那么作为下标变量的数组元素的类型也和函数形参变量的类型是一致的。
因此,并不要求函数的形参也是下标变量。换句话说,对数组元素的处理是按普通变量对待的。
用数组名作函数参数时,则要求形参和相对应的实参都必须是类型相同的数组,都必须有明确的数组说明。
当形参和实参二者不一致时,即会发生错误。

2) 在普通变量或下标变量作函数参数时,形参变量和实参变量是由编译系统分配的两个不同的内存单元。
在函数调用时发生的值传送是把实参变量的值赋予形参变量。在用数组名作函数参数时,不是进行值的传送,
即不是把实参数组的每一个元素的值都赋予形参数组的各个元素。因为实际上形参数组并不存在,编译系统不为形参数组分配内存。
那么,数据的传送是如何实现的呢?在我们曾介绍过,数组名就是数组的首地址。
因此在数组名作函数参数时所进行的传送只是地址的传送,也就是说把实参数组的首地址赋予形参数组名。
形参数组名取得该首地址之后,也就等于有了实在的数组。实际上是形参数组和实参数组为同一数组,共同拥有一段内存空间。

*******************************************************************************************/

#include
#include
#include
#include
#include

bit bflag;

void ser_init(void)
{
 SCON = 0x50;   //串口方式1,允许接收
 TMOD = 0x20;   //定时器1定时方式2
 TCON = 0x40;   //设定时器1开始计数
 TH1 = 0xE8;   //11.0592MHz 1200波特率
 TL1 = 0xE8;
 TI = 1;
 TR1 = 1;    //启动定时器
}

#if 0
//例10.2通过改变指针变量的值(指针的指向)来输出大小
void main(void)
{
 while(1)
 {
  if(!bflag)
  {
    int *p1,*p2,*p,a,b;
   ser_init();
   printf("input two numbers:\n");
   scanf("%d,%d",&a,&b);
   p1=&a;
   p2=&b;
   if(a
   {
    p=p1;
    p1=p2;
    p2=p;
   }
   printf("a=%d,b=%d\n",a,b);
   printf("max=%d,min=%d\n",*p1,*p2);
)

   bflag = 1;
  }
 }
 
}
#endif
//--------------------------------------------------------------------------------------------

#if 1
//例10.5自定义函数,指针作函数参数传递
//实参和形参共同指向变量a和b,不能通过改变形参的值而使实参发生改变.
//只有通过改变形参指向变量的值才使实参数据发生改变
void swap(int *p1,int *p2)
{
 int temp;
 temp = *p1;
 *p1 = *p2;
 *p2 = temp;
}

void exchange(int *q1,int *q2,int *q3)
{
 if(*q1 < *q2) swap(q1,q2);
 if(*q1 < *q3)  swap(q1,q3);
 if(*q2 < *q3) swap(q2,q3);

}

void main(void)
{
 while(1)
 {
  if(!bflag)
  {
   int a,b,c;
   int *pointer_1,*pointer_2,*pointer_3;
   ser_init();
   printf("input three numbers:\n");
   scanf("%d%d%d",&a,&b,&c);
   pointer_1 = &a;
   pointer_2 = &b;
   pointer_3 = &c;
   exchange(pointer_1,pointer_2,pointer_3);
   printf("%d,%d,%d\n",a,b,c);

   bflag = 1;
  }
 }
 
}

#endif

//------------------------------------------------------------------------------------
//实参的值没有发生交换,只有形参的值发生了交换
#if 0
void swap(x,y)
{
 int temp;
 temp = x;
 x = y;
 y = temp;
}

void main(void)
{
 while(1)
 {
  if(!bflag)
  {
   int a,b;
   ser_init();
   printf("input two numbers:\n");
   scanf("%d%d",&a,&b);
   swap(a,b);
   printf("%d,%d\n",a,b);
   bflag = 1;
  }
 }
 
}
#endif

//-----------------------------------------------------------------------------------
//下标法访问数组元素
#if 0
void main(void)
{
 int a[10],i;
 ser_init();
 for(i=0;i<10;i++)
 {
  a=i;
 }
 for(i=0;i<10;i++)
 {
  printf("a[%d]=%d\n",i,a);
 }
 
}
#endif

#if 0
//指针法间接访问数组元素和通过数组元素计算元素地址,找出元素的值
void main(void)
{
 int a[10],i,*p;
 ser_init();
 p=a;
 for(i=0;i<10;i++)
 {
 // a=i;
  *(a+i)=i; 
 }
 for(i=0;i<10;i++)
 {
  printf("a[%d]=%d\n",i,*(a+i));
 }
}
#endif
//------------------------------------------------------------------------------------------
//例10.15 指针作实参传递给指针形参
#if 0
float aver(float *pa)
{
 int i;
 float av=0,sum=0;
 for(i=0;i<5;i++) sum=sum + *pa++;
 av=sum/5;
 return av;  
}

void main(void)
{
 while(1)
 {
  if(!bflag)
  {
   int j;
   float sco[5],av,*sp;
   sp=sco;
   ser_init();
   printf("input five scores:\n");
   for(j=0;j<5;j++) scanf("%f",&sco[j]);
   av=aver(sp);
   printf("%5.2f\n",av);
   bflag = 1; 
  }
 }
 


}
#endif

//---------------------------------------------------------------------------------------
//选择法对10个整数排序
//思路:比如数组序列 10 45 8 55 45 41 23 17 85 63
//拿10跟后面9个数作比较,如果比9大就交换。如45比10大就跟把45的下标1存在10的下标0里,依此类推
#if 0
void SelectSort(int x[],int n)
{
 int i,j,k,t;
  
 for(i=0;i
    { 
  k=i;    //外循环一个数的下标暂存在变量k
     
  for(j=i+1;j
       {
   if(x[j]>x[k]) k=j;
  }
  
     if(k!=i)   //内循环循环一次,如果有比外循环大的数就交换数组元素的值
     {
   t=x;   //t为中间变量
   x=x[k];
   x[k]=t;
  }
    }
}
;j++) >;i++)  >

#endif

//冒泡排序原则,重者在下,轻者在上
#if 0
void BubbleSort(int x[],int n)
{
 int i,j,temp;
 bit bexchange;       //x0 x1 x2 x3...x(n-1)
 for(i=1;i
 {
  bexchange=0;
  for(j=n-1;j>=i;j--)
  {
   if(x[j+1] < x[j])
   {
    temp = x[j+1];
    x[j+1] = x[j];
    x[j] = temp;
    
    bexchange = 1;  
   }
   
  // if(!bexchange)  return;
    
  }
 }
}
;i++)

 

void main(void)

 while(1)
 {
  if(!bflag)
  {
   int *p,i,a[10]={3,7,9,11,0,6,22,5,4,2};
 
   ser_init();
  
   printf("The original array:\n");
   
   for(i=0;i<10;i++)  printf("%d,",a);
    
   printf("\n");
   
   p=a;
   
  // SelectSort(p,10);
   
   BubbleSort(p,10);
    
   for(i=0;i<10;i++)
   {
    printf("%d  ",*p);
    
    p++;   
   }
  
   printf("\n");
     
   bflag = 1;
  }
 }
 
}
#endif

//----------------------------------------------------------------------------------
//指向二维数组的指针变量
#if 0
void main(void)
{
 
 while(1)
 {
  if(!bflag)
  {
   
   int a[3][4]={
      0,1,2,3,
       4,5,6,7,
       8,9,10,11
       };
   int i,j;
   int (*p)[4];   //定义指向二维数组指针变量 
   ser_init();
   p = a;     //数组a的首行地址赋给二维数组指针变量p
 
   for(i=0;i<3;i++)
   {
    for(j=0;j<4;j++)
    {
     printf("%d  ",*(*(p+i)+j) );
     
    }

    printf("\n");
   }

   bflag = 1;
  }
 }
 
}
#endif


//-------------------------------------------------------------------------------------
//字符指针变量
#if 0
void main(void)
{
 while(1)
 {
  if(!bflag)
  {
   char *ps="I Love China!";
   int n=10;
   ser_init();
   printf("%s",ps);
   bflag = 1;
  }
 }
 
}
#endif
//--------------------------------------------------------------------------------------------

;i++)
;j++) >;i++)  >)

 

 

未完待续 下篇

PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

用户381337 2012-6-22 01:51

很好的资料,已经知道的人,在多看看,不懂得人加把劲
相关推荐阅读
用户1409899 2013-10-31 14:46
modbus协议crc-16算法
/------------------------------------- #if 0 #define uchar unsigned char #define uint  unsig...
用户1409899 2013-10-31 14:42
堆栈指针
  一道嵌入式系统设计师堆栈指针考题引发的思考: 在8086微处理器中,若(SS)=2000H,(SP)=0100H,(AX)=2117H,执行指令 PUSHAX后存放数据21H的物理...
用户1409899 2013-10-24 16:51
转载 :数据结构内存对齐
内存对齐 在我们的程序中,数据结构还有变量等等都需要占有内存,在很多系统中,它都要求内存分配的时候要对齐,这样做的好处就是可以提高访问内存的速度。 我们还是先来看一段简单的程序: 程序一 ...
用户1409899 2013-01-14 09:51
中星微zc301b摄像头
  硬件环境:友善之臂mini2440开发板+中星微zc301b摄像头 软件环境:linux2.6.29内核+上位机Ubuntu8.04 日    期:2012-12-1...
用户1409899 2012-07-05 19:44
国嵌mp3播放器应用程序
************************************************* Function name: main Parameter    : void Descr...
用户1409899 2012-07-05 19:43
国嵌mp3播放器应用程序
1.掌握双向循环链表,对指针,结构体,动态分配内存等C语言要求较高 2.掌握多进程编程,以及共享内存通信相关方面的内容     /*  *     mp3播放器控制程序  * ...
我要评论
1
9
关闭 站长推荐上一条 /3 下一条