注:本笔记为直接上传,因各个markdown笔记语法的差异性,在显示上略有区别。
如需原版请联系:gjx1690048420@163.com。(邮件主题为:学习笔记,正文需要的笔记名,可以直接复制该笔记的网址)。同时欢迎各位一起学习交流。

day9 指针

@toc

一、指针的含义和定义

#include<stdio.h>

int  main()

{

  int  buf[3][5]  =  {{2,4,3,5,3},{7,2,6,8,1},{7,3,5,0,2}};
  int  (*p)[5];
  p  =  buf;

  int  i;
  int  j;
  float  _aver_hang  =  0;
  float  _aver_lie  =  0;
  float  _sum_hang  =  0;
  float  _sum_lie  =  0;
  for(i  =  0;  i  <  3;  i++)
  {
    for(j  =  0;  j  <  5;  j++)
      {

        _sum_hang  +=  p[i][j];
        _aver_hang  =  _sum_hang  /  3.0;
      }

  printf("%d\n",_aver_hang);

  }

  return  0;

}

7.const保护函数参数以及返回值为指针的函数

通过函数的指针参数可以间接的实现形参修改实参的值;

  • 无法传值的程序
#include<stdio.h>

void test(int p)
{
  p++;
}

int main()
{
  int i = 0;
  test(i);
  printf("i = %d\n",i);
  return 0;

}

程序运行结果:i = 0
因为形参的值不能反过来传给实参

  • 可以传值的程序
    想改变实参的值需要使用指针;
#include<stdio.h>

void test(int *p)
{
  (*p)++;  //*p为i的值,则对应的是i+1;

}

int main()
{
  int i = 0;
  test(&i);  //传给形参的是实参i的地址
  printf("i = %d\n",i);
  return 0;

}

程序结果为:i=1;


8.交换两个数据的值:

#include<stdio.h>

void swap(int *c,int *d)
{
  int tmp = *c; //*c即是a的值
  *c = *d;
  *d = tmp;
}

int main()
{
  int a = 10;
  int b = 20;
  swap(&a,&b);  //传递的是地址
  printf("a = %d, b = %d",a,b);
}

程序运行结果:a = 20, b = 10


9.将一维数组名作为函数参数
数组名代表数组的首地址

#include<stdio.h>

void set_array(int buf1[])  //当一维数组名作为函数的参数的时候,数组名其实就是一个指针变量
 //上面那行代码等效为:void set_array(int *buf1)
  {
    buf1[0] = 100;
    buf1[1] = 200;
  }


void print_array(int buf2[])
{
  int i;
  for(i = 0;i < 10; i++)
  {
    printf("buf[%d] = %d\n",i,buf2[i]);
  }

}


int main()
{
  int buf[10] = {1,2,3,4,5,6,7,8,9,10};
  set_array(buf);  //放的是数组的首地址
  print_array(buf);
  return 0;
}

当参数为指针的时候,应该同时定义指针的维度

#include<stdio.h>

void print_array(int *buf2 , int n)
{
  int i;
  for(i = 0;i < n; i++)
  {
    printf("buf[%d] = %d\n",i,buf2[i]);
  }

}


int main()
{
  int buf[] = {1,2,3,4,5,6,7,8,9,10};
  print_array(buf,sizeof(buf)/sizeof(int)); //自动将buf的长度获取
  return 0;
}

10.将二维数组名作为函数参数

#include<stdio.h>

void print_array(int (*p)[3],int a,int b)  //这里的维度3一般不可更改,而且实际中二维数组作为函数的参数的示例很少使用
//等效写法 void print_array(int p[][3],int a,int b)
{
   int i;
   int j;
   for(i = 0;i < a; i++)
   {
     for(j = 0; j < b; j++)
     {
       printf("p[%d][%d] = %d\n",i,j,p[i][j]);

     }

   }

}

int main()
{
  int buf[2][3] = {{1,2,3},{4,5,6}};

// print_array(buf,2,3);  这是行数和列数都是写死的
 //如果想将二维数组的行数和列数改变,仍然不妨碍其他的程序进行
  print_array(buf,sizeof(buf)/sizeof(buf[0]),sizeof(buf[0])/sizeof(int));


//以下程序是常见的打印行列数的代码
printf("shuzuchangdu  =  %d\n",sizeof(buf));

printf("diyihangchangdu  =  %d\n",sizeof(buf[0]));

printf("hangshu  =  %d\n",sizeof(buf)/sizeof(buf[0]));

printf("lieshu  =  %d\n",sizeof(buf[0])/sizeof(int));

   return 0;
}

11.const保护函数参数
当部分的函数参数不需要被修改的时候,可以使用const进行保护
如果将一个数组作为函数的形参传递,那么数组的内容可以在被调用的函数内部进行修改,如果不希望被修改,可以对形参采用const参数

示例: 将数组s1和s2进行合并,则对于传过来的s2的值是不应该改变的

#include<stdio.h>

void mystrcat(char *a, const char *b)   //第二个形参的值不希望被改变,,使用const可以避免被改变

{

  int len = 0;
  while(b[len])
  {
    len++;
  }

  while(*a)
  {
    a++;
  }


//*b = 10;    这个语句会被报错
  int i;
  for(i = 0; i < len; i++)
    {
      *a = *b;
      a++;
      b++;
    }

}

int main()
{
  char s1[10] = "abc";
  char s2[10] = "def";
  mystrcat(s1,s2);
  printf("s1 = %s\n",s1);
  return 0;

}

12.指针作为函数的返回值

示例: 实现查找数组中是否含有某个字符

#include<stdio.h>

char *mystrchar(char *s,char b)
{
  while(*s)
  {
    if(*s == b)
    return s;
    s++;
  }

  return NULL;
}

int main()
{
   char str[20] ="hello world";
   char *la = mystrchar(str,'o');
   printf("str = %s\n",la);
   return 0;

}

13.char指针与字符串以及返回值为指针的函数
通过指针访问字符串数组

#include<stdio.h>

int main()
{
  int buf[20] = "hello world";

  char *p = buf;
  //以下的代码之间是相互等效的
  *(p + 5) = 'a';
  p[5] = 'b';   //上面这两个中p 的大小没变

  p +=5;
  *p = 'c';   //p变成了5

  printf("buf = %s\n",buf);


}

数组做参数和字符串做参数的区别

#include<stdio.h>

void print_array(int *p ,int n)  //如果参数为一个int数组,那么必须传递第二个参数用来表示维度
{
  int i;
  for(i = 0; i < n; i++)
  {
      printf("p[%d] = %d\n",i,p[i]);
  }
}

void print_str(char *s)
{
  int i = 0;
  while(s[i])
  {
    printf("%c",s[i++]);  //这句要记住
  }

}

int main()
{
  int a[10] = {1,2,3,4,5};
  print_array(a,10);

  char b[20] = "hello world";
  print_str(b);

  return 0;

}

14.两种打印字符串的方法:
\0是否继续打印后面的字符

  • 正常情况下遇到\0即默认字符串到达结尾,停止打印,程序为:
#include<stdio.h>

void print_str(char *p)
{
  //下面有两种写法:
  while(*p)
  {
    printf("%c",*p);
    p++;
  }

  int i = 0;
  while(s[i])
  {
    printf("%c",s[i++]);
  }


}


int main()
{
char buf[20] = "hello world";
buf[3] = 0;

print_str(buf);
return 0;

}

该程序的结果为:hel

  • 如果想让该字符串仅仅按照字符串的长度来输出,不受\0的约束
#include<stdio.h>

void print_str(char *s,int len)
{
  int i = 0;
  for(i = 0; i < len; i++)
  {
    printf("%c",s[i]);
  }

}

int main()
{
  char s[20] = "hello world";
  s[3] = 0;
  print_str(s,sizeof(s));   //打印的长度是数组定义的长度
  return 0;

}

程序运行结果:hel o world


10-03 19:43