C语言学习记录——7000+字长文-复习&学习指针(指针、地址、指针变量、指针与数组、指针与函数、指针数组、多级指针)二

简介: C语言学习记录——7000+字长文-复习&学习指针(指针、地址、指针变量、指针与数组、指针与函数、指针数组、多级指针)二

C语言学习记录——7000+字长文-复习&学习指针(指针、地址、指针变量、指针与数组、指针与函数、指针数组、多级指针)一:https://developer.aliyun.com/article/1530354

字符数组与字符指针

可以用字符串常量来给字符型指针进行初始化。

int *str1 = "How are you !";
//此时字符指针指向的是一个字符串常量的首地址,即指向字符串的首地址。
 
int *str2[] = "How are you !";
//此时,str2是字符数组,它存放的是一个字符串。

字符指针str1与字符数组str2的区别是:


str1是一个变量,可以改变str1的值,即str1可以指向不同内存单元的地址。



指针字符数组的指针

定义一个字符指针指向字符数组后,就可以利用指针来处理该字符数组中存储的字符串。使用指针处理字符串,不仅书写方便,而且程序的运行效率更高。

用指针处理字符串的方法是:首先定义一个字符指针,然后将字符数组的首地址赋值给该指针。

例如:

char str[] = "Hello world !";
char *p = str;

看下面一段代码:

#include <stdio.h>
int main()
{
  char str[] = "Hello world !";
  char *p = str;     
  printf("%s\n", p);
  p += 6;
  printf("%s\n", p);
  return 0;
}


其运行结果为:

其中p初始化时存储了str的首地址,故打印出来了完整的字符串。

而后将指针p往后移了6位,使得其新的首地址从‘w’开始,所以打印出来的结果变成了“world!”。

指针与函数

 

函数型指针的定义

在C语言中,定义了函数之后,系统为该函数分配一段连续的存储空间。其中函数的起始地址称为该函数的入口地址,将此地址赋给另外一个变量,则该变量为一个指向函数的指针。

指向函数的指针变量的一般形式为:

类型说明符(* 标识符)();

其中,类型说明符为被指针所指向的函数的返回值的数据类型;标识符为一个指针名(不是函数名),该指针只能指向函数;括号中为空,但括号必须有,表示该指针是专指函数的。

例如:

int (*p)();

函数型指针的赋值

用函数名为指针初始化,表示指针指向该函数。

例如:

int (*p)();   //定义函数型指针
int fun();    //声明函数fun
p = fun;      //让指针p指向函数fun

关于函数型指针的赋值说明:

(1)当函数型指针指向了某一函数后,此函数的调用可以用函数名,也可以用指针(用*p代替原函数名);

(2)用函数型指针定义之后,不是固定指向某一个函数,而是先后指向不同的函数(给它赋值其他入口地址即可改变其指向的函数);

(3)为函数型指针赋值时,不必用参数;

(4)对指向函数的指针变量,先p + n,p ++,p -- 等运算是没有意义的。

指针型函数的定义与使用

调用函数,通常得到一个返回值带回主调函数。如果返回值为一个指针时,则该函数就是指针型函数。

定义形式:

类型说明符  *标识符(形参列表);

例如:

int *a(int x,int y);

其中a是函数名,调用它以后能得到一个指向整型数据的指针。x、y是函数a的形参,为整型。因此,指针型函数也就是返回指针值的函数。

 

利用指针型函数,求一个二维数组中的最大值,并返回它的地址

#include <stdio.h>
#define ROW 3   //宏定义二维数组的行和列
#define COL 4
 
int* max(int a[ROW][COL])
{
  int *p, i, j;
  p = a[0];
  for (i = 0; i < ROW; i++)
  {
    for (j = 0; j < COL; j++)
    {
      //判断大小
      if (*p < *(*(a + i) + j))
        p = *(a + i) + j;
    }
  }
  return p;
}
 
int main()
{
  int a[ROW][COL], i, j, * p;
  printf("请输入二维数组值:");
  for (i = 0; i < ROW; i++)
  {
    for (j = 0; j < COL; j++)
    {
      scanf("%d", &a[i][j]);
    }
  }
  //将二维数组传参进函数a
  p = max(a);
  for (i = 0; i < ROW; i++)
  {
    for (j = 0; j < COL; j++)
    {
      printf("%d\t", a[i][j]);
    }
    printf("\n");
  }
  printf("最大值为:%d\n", *p);
  return 0;
}

其运行结果为:

 

指针数组

由若干个指针变量组成的数组,称为指针数组。指针数组也是数组的一种,所有有关数组的概念都适用它。但指针数组与普通数组又有区别,指针数组的数组元素是指针类型的,只能用来存放地址值。

指针数组的定义

定义形式:

类型说明符  *数组名[数组长度];

例如:

int *p[4];

这条语句定义了一个指针数组p,该数组中有4个元素,每个元素都是一个指针,指向int型数据。指针数组比较适合用来指向若干个字符串,使字符串处理更加方便灵活。


值得注意的是:


指针数组语句:int *p[ 4 ];符号[]的优先级比符号*高,因此变量名p先与[]结合,表示这是一个长度为4的数组;再与*和int结合,表示该数组的元素的数据类型是int * 型,每个数组元素都可以指向一个整型变量。  

指针数组的初始化

指针数组是由若干个指针变量组成的数组,因此必须用地址值为指针数组初始化。

例如:

int arr[3][3] = {1,2,3,4,5,6,7,8,9};
 
int *pa[3] = {arr[0],arr[1],arr[2]};

由于arr是一个二维数组,所以arr[ 0 ],arr[ 1 ],arr[ 2 ]为该二维数组的每一行的首地址。

故而,可以通过指针数组来引用二维数组中的元素:

pa[i] + j = arr[i] + j = &arr[i][j];
 
*(pa[i] + j) = *(arr[i] + j) = arr[i][j]; 

用字符指针数组表示一组字符串,即每个数组元素分别指向一个字符串,然后进行字符串的比较:

 

#include <stdio.h>
#include <string.h>
int main()
{
  char *s[4] = { "hello","Circle","Square","Rectangle" };
  char *temp;
  int i, j, k;
  for (i = 0; i < 4; i++)
  {
    printf("%d:%s\n", i + 1, s[i]);  //按原始顺序输出4个字符串
  }
  for (i = 0; i < 3; i++)
  {
    //使得前一个字符串与后面几个字符串对比
    k = i;
    for (j = i + 1; j < 4; j++)
    {
      if (strcmp(s[k], s[j]) > 0)
        k = j;
      if (k != i)
      {
        temp = s[i];
        s[i] = s[k];
        s[k] = temp;       //交换指针指向的字符串
      }
    }
        
  }
  printf("\n");
  for (i = 0; i < 4; i++)
  {
    printf("%d:%s\n", i + 1, s[i]);   //输出排序后的4个字符串
  }
  return 0;
}

其运行结果为:

 

多级指针

如果一个指针变量存放的是另一个指针变量的地址,则称这个指针变量为指向指针的指针变量,即多级指针(指向指针的指针)

多级指针定义的一般形式如下:

类型说明符  * * 指针名;

例如:

int x = 4;
int *p ;
int **p ;
p = &x;   //指针变量p指向整型变量x
q = &p;   //二级指针q指向指针变量p

看下面代码:

#include <stdio.h>
int main()
{
  int x = 10;
  int *p, **q;
  p = &x;
  q = &p;
  printf(" x = %d\n", x);
  printf(" *p = %d\n", *p);
  printf(" **q = %d\n", **q);
  return 0;
}

其运行结果为:

所以说,以上三种方式都是等价的。

要注意的:指向指针的指针是间接地指向目标变量,因此,将直接指向目标变量的指针称为一级指针,将指向指针的指针称为二级指针,将指向二级指针的指针称为三级指针,以此类推。

通过指向指针的指针输出数组元素:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
  srand((unsigned int)time(NULL));
  int arr[5][3],a,b,**p;
  int *num[5] = { arr[0],arr[1],arr[2],arr[3],arr[4] }; //指针数组
  p = num;  //指向指针数组的指针
  for (a = 0; a < 5; a++)   //随机初始化二维数组
  {
    for (b = 0; b < 3; b++)
    {
      arr[a][b] = rand() % 20 + 1;
    }
  }
 
  for (a = 0; a < 5; a++)   
  {
    for (b = 0; b < 3; b++)
    {
      printf("%2d\t", *(*p + b));  //通过二级指针输出数组元素
    }
    printf("\n");
    p++;
  }
  return 0;
}

其运行结果为:

目录
相关文章
|
18天前
|
C语言
【c语言】指针就该这么学(1)
本文详细介绍了C语言中的指针概念及其基本操作。首先通过生活中的例子解释了指针的概念,即内存地址。接着,文章逐步讲解了指针变量的定义、取地址操作符`&`、解引用操作符`*`、指针变量的大小以及不同类型的指针变量的意义。此外,还介绍了`const`修饰符在指针中的应用,指针的运算(包括指针加减整数、指针相减和指针的大小比较),以及野指针的概念和如何规避野指针。最后,通过具体的代码示例帮助读者更好地理解和掌握指针的使用方法。
44 0
|
17天前
|
存储 C语言 C++
如何通过指针作为函数参数来实现函数的返回多个值
在C语言中,可以通过将指针作为函数参数来实现函数返回多个值。调用函数时,传递变量的地址,函数内部通过修改指针所指向的内存来改变原变量的值,从而实现多值返回。
|
17天前
|
C语言
【c语言】指针就该这么学(3)
本文介绍了C语言中的函数指针、typedef关键字及函数指针数组的概念与应用。首先讲解了函数指针的创建与使用,接着通过typedef简化复杂类型定义,最后探讨了函数指针数组及其在转移表中的应用,通过实例展示了如何利用这些特性实现更简洁高效的代码。
13 2
|
17天前
|
存储 搜索推荐 C语言
如何理解指针作为函数参数的输入和输出特性
指针作为函数参数时,可以实现输入和输出的双重功能。通过指针传递变量的地址,函数可以修改外部变量的值,实现输出;同时,指针本身也可以作为输入,传递初始值或状态。这种方式提高了函数的灵活性和效率。
|
17天前
|
C语言
如何避免 C 语言中的野指针问题?
在C语言中,野指针是指向未知内存地址的指针,可能引发程序崩溃或数据损坏。避免野指针的方法包括:初始化指针为NULL、使用完毕后将指针置为NULL、检查指针是否为空以及合理管理动态分配的内存。
|
17天前
|
C语言
C语言:哪些情况下会出现野指针
C语言中,野指针是指指向未知地址的指针,通常由以下情况产生:1) 指针被声明但未初始化;2) 指针指向的内存已被释放或重新分配;3) 指针指向局部变量,而该变量已超出作用域。使用野指针可能导致程序崩溃或不可预测的行为。
|
23天前
|
存储 算法 C语言
C语言:什么是指针数组,它有什么用
指针数组是C语言中一种特殊的数据结构,每个元素都是一个指针。它用于存储多个内存地址,方便对多个变量或数组进行操作,常用于字符串处理、动态内存分配等场景。
|
17天前
|
编译器 C语言
【c语言】指针就该这么学(2)
本文详细介绍了指针与数组的关系,包括指针访问数组、一维数组传参、二级指针、指针数组和数组指针等内容。通过具体代码示例,解释了数组名作为首元素地址的用法,以及如何使用指针数组模拟二维数组和传递二维数组。文章还强调了数组指针与指针数组的区别,并通过调试窗口展示了不同类型指针的差异。最后,总结了指针在数组操作中的重要性和应用场景。
15 0
|
1月前
|
C语言
无头链表二级指针方式实现(C语言描述)
本文介绍了如何在C语言中使用二级指针实现无头链表,并提供了创建节点、插入、删除、查找、销毁链表等操作的函数实现,以及一个示例程序来演示这些操作。
20 0
|
2月前
|
存储 人工智能 C语言
C语言程序设计核心详解 第八章 指针超详细讲解_指针变量_二维数组指针_指向字符串指针
本文详细讲解了C语言中的指针,包括指针变量的定义与引用、指向数组及字符串的指针变量等。首先介绍了指针变量的基本概念和定义格式,随后通过多个示例展示了如何使用指针变量来操作普通变量、数组和字符串。文章还深入探讨了指向函数的指针变量以及指针数组的概念,并解释了空指针的意义和使用场景。通过丰富的代码示例和图形化展示,帮助读者更好地理解和掌握C语言中的指针知识。
下一篇
无影云桌面