入门学习计算机第十六天——指针进阶(一)

入门学习计算机第十六天——指针进阶(一)

编译器:Microsoft Visual Studio 2010

前言

字符指针

字符指针: char*

int main()
{
    char* p ="abcdef";//"abcdef"是一个常量字符串,指针内存放的是首元素的地址。
    printf("%c\n",*p);
    printf("%s\n",p);
   return 0;

}

输出的结果是
a
abcdef

有一道笔试题:

int main()
{
 char arr1[]= "abcdef";
 char arr2[]= "abcdef";
 const char* p1 ="abcdef";
 const char* p2 ="abcdef";
 if(arr1 == arr2)
   {
      printf("hehe\n");
   }
  else
  {
     printf("haha\n");
  }
  if(p1 == p2)
  {
     printf("hehe\n");
  }
 else
 {
    printf("haha\n");
 }
  return 0;
}

输出的结果是
haha
hehe

为什么输出haha?
arr1 与 arr2 是两个数组,创建了两个不同的空间,所以两个数组的首元素地址也不相同。
为什么输出hehe?
p1与p2指向的是同一个常量字符串,并且内容都是不可修改的。C会把常量字符串储存到单独的一个内存区域,当几个指针指向同一个字符串的时候,他们实际指向同一块内存,所以p1,p2指向的是一个空间,所以是相等的。

指针与数组

指针数组

主体是数组
int* arr[10];//整型指针的数组
char* arr2[4];//一级字符指针的数组
char** arr3[5];//二级字符指针的数组

int main()
{
   char arr1[] = {1,2,3,4,5};
   char arr2[] = {2,3,4,5,6};
   char arr3[] = {3,4,5,6,7};
   const char* parr []= {arr1, arr2 ,arr3};
    int  i =0;
    for(i = 0; i < 3 ; i++)
    {
        int j = 0;
        for(j = 0; j <5; j++)
        {
             printf("%d", *(parr[i]+j));
        }
    printf("\n");
    } 

}

入门学习计算机第十六天——指针进阶(一)_第1张图片

数组指针

主体是指针
数组指针,能够指向数组的指针

int main()
{
    int* p =NULL;//p是整型指针,指向整型的指针,存放整型的地址
    char* pc = NULL;//pc是字符指针,指向字符的指针,存放字符的地址
    int arr[10]={12345678910}int(*p)[10] = &arr;//数组的地址要存起来
    //上面的p就是数组指针,p先和*结合,说明p是一个指针变量,然后指向的是一个大小为10个整型的数组
   return 0;
}
void print(int arr[3][5],int x ,int y)
{
   int i = 0;
   int j =0;
  for(i = 0; i<x ;i++ )
  {
     for(j=0; j<y; j++)
     {
        printf("%d ", arr[i][j])
     }
  }
}
void print(int (*pa)[5],int x ,int y)
{
   int i = 0;
  for(i = 0; i<x ;i++ )
  {
     for(j=0; j<y; j++)
     {
        printf("%d ", *(*(pa+i)+j));
     }
  }
int main()
{
   arr[3][5]= {{1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7}};
   print(arr,3,5);//参数是数组的形式
   printf2(arr,3,5);//参数是指针的形式
}

输出的结果都是
12345
23456
34567

由上述的代码可知

printf("%d ",p[i][j]);
printf("%d ",*(p[i]+j));
printf("%d ",*(*(p+i)+j));
printf("%d ", *(p+i)[j]);  //四种方式都等价

int arr[5];

arr是一个5个元素的整型数组

int* parr1[5];

parr1是一个数组,数组内有5个元素,每一个元素的类型是Int* ,parr1是一个指针数组

int (*parr2)[5];

parr2是一个指针,该指针指向一个5个元素的整型数组

int(*parr3[10])[5];

parr3是一个数组,该数组有10个元素,每一个元素是一个数组指针
该数组指针指向的数组有5个元素,每个元素的类型是int

入门学习计算机第十六天——指针进阶(一)_第2张图片

数组参数,指针参数

一维数组传参

void test(int arr[])
{}
void test(int arr[10])
{}
void test(int* arr)
{}
void test2(int *arr[20])
{}
void test2(int **arr)//所有函数的传参都是正确的
{}
int main()
{
  int arr[10] = {0};
  int *arr2[20] = {0};
  test(arr);
  test2(arr2);
  return 0
}

二维数组传参

void test(int *arr)//err
{}
void test(int* arr[5])//err
{}
void test(int (*arr)[5])//正确
{}
void test(int **arr)//err
{}
int main()
{
  int arr[3][5]={0};
  test(arr);
}

一级指针传参

void print(int *p , int sz)
{
  int i = 0;
  for(i=0; i<sz; i++)
  {
     printf("%d ",*(p+i));
  }
}
int main()
{
   int arr[10] = {1,2,3,4,5,6,7,8,9,10};
   int *p =arr;
   int sz = sizeof(arr)/sizeof(arr[0]);
   print(p,sz);
}

思考:test和test2能接收什么参数

void test(int* p)
{}
void test2(char* p)
{}
int a =10;
test(&a);
//或者
int a =10;
int *p =&a;
test(p);
//test2同理

二级指针传参

void test(int** ptr)
{
    printf("num= %d\n", **ptr);
}
int main()
{
   int n =10;
   int* p =&n;
   int **p =&p;
   test(pp);
   test(&p);
   int* arr[10];
   test(arr);//指针数组也可以
   return 0;
}

你可能感兴趣的:(入门到入坟,菜鸟入门,指针,c语言)