c语言 指针 p=i,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) 在普通变量或下标变量作函数参数时,形参变量和实参变量是由编译系统分配的两个不同的内存单元。

在函数调用时发生的值传送是把实参变量的值赋予形参变量。在用数组名作函数参数时,不是进行值的传送,

即不是把实参数组的每一个元素的值都赋予形参数组的各个元素。因为实际上形参数组并不存在,编译系统不为形参数组分配内存。

那么,数据的传送是如何实现的呢?在我们曾介绍过,数组名就是数组的首地址。

因此在数组名作函数参数时所进行的传送只是地址的传送,也就是说把实参数组的首地址赋予形参数组名。

形参数组名取得该首地址之后,也就等于有了实在的数组。实际上是形参数组和实参数组为同一数组,共同拥有一段内存空间。

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

#i nclude

#i nclude#i nclude#i nclude#i nclude

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=%dn",a,b);

printf("max=%d,min=%dn",*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,%dn",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,%dn",a,b);

bflag = 1;

}

}

}

#endif

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

//下标法访问数组元素

#if 0

void main(void)

{

int a[10],i;

ser_init();

for(i=0;i<10;i++)

{

a[i]=i;

}

for(i=0;i<10;i++)

{

printf("a[%d]=%dn",i,a[i]);

}

}

#endif

#if 0

//指针法间接访问数组元素和通过数组元素计算元素地址,找出元素的值

void main(void)

{

int a[10],i,*p;

ser_init();

p=a;

for(i=0;i<10;i++)

{

// a[i]=i;

*(a+i)=i;

}

for(i=0;i<10;i++)

{

printf("a[%d]=%dn",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.2fn",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[i];   //t为中间变量

x[i]=x[k];

x[k]=t;

}

}

}#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;

}

}

}

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[i]);

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

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

未完待续 下篇

技术资讯 技术方案 技术应用 技术新品 技术前沿 行业资讯 行业方案 行业应用 行业新品 行业前沿

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值