指针

每一个变量都有一个内存位置,每一个内存位置都定义了可使用 & 运算符访问的地址,它表示了在内存中的一个地址。 指针也就是内存地址,指针变量是用来存放内存地址的变量。

指针的声明

int    *ip;    /* 一个整型的指针 */
double *dp;    /* 一个 double 型的指针 */
float  *fp;    /* 一个浮点型的指针 */
char   *ch;    /* 一个字符型的指针 */

注:所有实际数据类型,不管是整型、浮点型、字符型,还是其他的数据类型,对应指针的值的类型都是一样的,都是一个代表内存地址的长的十六进制数。不同数据类型的指针之间唯一的不同是,指针所指向的变量或常量的数据类型不同。

使用指针

使用指针时会频繁进行以下几个操作:定义一个指针变量、把变量地址赋值给指针、访问指针变量中可用地址的值 在这里插入图片描述

#include <stdio.h>
int main ()
{
   int  var = 20;   /* 实际变量的声明 */
   int  *ip;        /* 指针变量的声明 */
   ip = &var;  /* 在指针变量中存储 var 的地址 */
   printf("var 变量的地址: %p\n", &var  );
   /* 在指针变量中存储的地址 */
   printf("ip 变量存储的地址: %p\n", ip );
   /* 使用指针访问值 */
   printf("*ip 变量的值: %d\n", *ip );
   return 0;
}

运行结果为:

var 变量的地址: 0x7ffeeef168d8
ip 变量存储的地址: 0x7ffeeef168d8
*ip 变量的值: 20

注:单说一个指针名代表的是地址,指针名+“*”可以代表指针中存储的变量

结构体指针

结构体中的指针

指针与其他一样也是一种数据类型,也可以在结构体中声明:

#include <stdio.h>
typedef struct
{
    float temperature; //温度
    char humidity;     //湿度
    char alcohol;      //酒精浓度
    int illumination;  //光照强度
    char CO;           //一氧化碳浓度
    int *p;            // int型的指针变量
} sensor;

sensor sen;   //定义结构体变量
int value = 0;

int main(void)
{
    sen.p=&value;//对value的地址赋值 
    printf("value=%d\r\n",*(sen.p));
    printf("%d\r\n",sen.p);}

在这里插入图片描述 上面的例子相当于将结构体中的p指针指向了变量value的地址

指向结构体的指针

定义指向结构的指针,方式与定义指向其他类型变量的指针相似

sensor *Psen;

可以在上述定义的指针变量中存储结构变量的地址。为了查找结构变量的地址,把 & 运算符放在结构名称的前面:

Psen = &sen;

为了使用指向该结构的指针访问结构的成员,必须使用 -> 运算符:

Psen->humidity=20;

一个例子:

#include <stdio.h>
typedef struct
{
    float temperature; //温度
    char humidity;     //湿度
    char alcohol;      //酒精浓度
    int illumination;  //光照强度
    char CO;           //一氧化碳浓度
    int *p;            // int型的指针变量
    void (*fun)();     //定义一个函数指针
} sensor;
sensor sen;//结构体变量sen
sensor *Psen;//结构体指针变量Psen
int main(void)
{
    Psen = &sen;//结构体指针变量赋值
    Psen->humidity=20;//设置结构体成员变量

    printf("humidity=%d\r\n",Psen->humidity);

}

在这里插入图片描述

宏定义

在这里插入图片描述

无参宏

无参宏即宏名之后不带参数,只是简单的文本替换

#define M 5                // 宏定义
#define PI 3.14            //宏定义
int a[M];                  // 会被替换为: int a[5];
int b = M;                 // 会被替换为: int b = 5;
printf("PI = %.2f\n", PI); // 输出结果为: PI = 3.14

有参宏

带参数的宏定义,宏名中不能有空格,宏名与形参表之间也不能有空格,而形参表中形参之间可以有空格 输出一个数的平方:

#define COUNT(M) M*M
int x=6;
print(COUNT(x+1));
print(COUNT(++X));

typedef

C 语言提供了 typedef 关键字,可以使用它来为类型取一个新的名称 例如,可以对结构体使用 typedef 来定义一个新的数据类型名字,然后使用这个新的数据类型来直接定义结构变量,

#include <stdio.h>
#include <string.h>
 
typedef struct Books
{
   char  title[50];
   char  author[50];
   char  subject[100];
   int   book_id;
} Book;
 
int main( )
{
   Book book;
 
   strcpy( book.title, "C 教程");
   strcpy( book.author, "Runoob"); 
   strcpy( book.subject, "编程语言");
   book.book_id = 12345;
 
   printf( "书标题 : %s\n", book.title);
   printf( "书作者 : %s\n", book.author);
   printf( "书类目 : %s\n", book.subject);
   printf( "书 ID : %d\n", book.book_id);
 
   return 0;
}

define与typedef区别

宏定义只是简单的字符串代换,在预处理阶段完成。而typede不是简单的字符串代换,而是可以用来做类型说明符的重命名的,类型的别名可以具有类型定义说明的功能,在编译阶段完成的。 两者都可以表示数据类型 但有当定义指针类型的变量时

#define INT1 int *
typedef int * INT2;
INT1 a1, b1;
INT2 a2, b2;

INT1 a1,b1;被替换后为 int *a1,b1;即一个指向int类型的指针一个int类型的变量 INT2 a2,b2;则是两个指向int类型的指针