指针
每一个变量都有一个内存位置,每一个内存位置都定义了可使用 & 运算符访问的地址,它表示了在内存中的一个地址。
指针也就是内存地址,指针变量是用来存放内存地址的变量。
指针的声明
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类型的指针