理解c语言结构体指针

新手理解c语言指针


void changeI(int i) {
	i = 25;
	printf("changeI:%d\n", i);
}

void changeI(int *p) {
	*p += 2;
	printf("changeI:%d\n", *p);
}

void changeP(int *p) {
	p = NULL;
	printf("changeP:%d\n", p);
}

int main()
{
	int i = 21, j = i;
	int *p1 = &i, *p2 = &i;
	*p1 = 23;
	printf("i:%d\n", i);
	printf("j:%d\n", j);
	printf("p1:%d\n", *p1);
	printf("p2:%d\n", *p2);

	changeI(i);
	printf("i:%d\n", i);
	changeI(&i);
	printf("i:%d\n", i);
	changeI(p1);
	printf("i:%d\n", i);

	changeP(p2);
	printf("p2:%d\n", p2);

}

如上所示:
在这里插入图片描述
代码仅用于本示例,不纠文件结构,函数申明什么的。
从主函数从上往下输出:
前四个输出 :

  1. i = 21, j = i;是常见的赋值语句,即变量j的值现在为21。
  2. *p1 = &i, *p2 = &i;现在p1,p2均为i的地址。
  3. *p1 = 23;在主函数中很容易理解,将p指向的地址的值改为23,而p1本身的值没变,p2与p1的值相同,均指向变量i在内存中的地址,此地址的值现在被修改为23,即i的值现在为23。
  4. 前三条对应四个printf()。
  5. 第一个changeI中,我们传入的i,系统以值得方式传入,即传入的不是变量i,而是变量i的值,即传入了23;在函数内的i为函数局部变量,值为23,所以+=2得到25,随后输出25;
  6. 回到主函数,再次输出i,主函数中的i未发生变化。
  7. 第二个changeI,传入i的地址,此时传入的则对应主函数中的变量i,因此在函数内改变了主函数中的i,输出两次均为23+=2的结果;
  8. 随后changeI,传入p1的值,即传入了变量i的地址,同上,输出了两次27。
  9. changeP中,我们传入了p2的值,即i的地址,然后将此值赋值为NULL,注意:p2仅记录了i的地址, 其值得变化并不会导致i得地址发生变化,因此i与p1都为收到影像,且p2由于传值得原因,也为收到影响。最后两次输出的值分别为NULL与i得地址。
    思考如何在函数中改变p2的值
    我们应该将p2得地址传入函数。p2记录了i得地址,但其本身也是变量,也存在内存中,也有地址。
    思考将int类型变成结构体
    如果我们定义指针,而不定义变量,希望给指针所指区域赋值,则需要先申请空间。
typedef struct MyStruct
{
	int ID;
	char name[7];
	int age;
} stu1;


void setValue(stu1 stu, int ID, char name[7], int age) {
	stu.ID = ID;
	for (int i = 0; i < 7; i++) {
		stu.name[i] = name[i];
	}
	stu.age = age;
}

void setValue(stu1 *stu, int ID, char name[7], int age) {
	(*stu).ID = ID;
	for (int i = 0; i < 7; i++) {
		(*stu).name[i] = name[i];
	}
	stu->age = age;
}

void printStu(stu1 stu) {
	printf("ID:%d\t", stu.ID);
	printf("name:%s\t", stu.name);
	printf("age:%d\n", stu.age);
}

int main()
{
	stu1 *st = (stu1*)malloc(sizeof(stu1));
	stu1 stu;
	char name[] = "张三";
	stu.ID = 2000;
	setValue(stu, 2000, name, 18);
	printStu(stu);

	char name1[] = "李四";
	setValue(st, 2001, name1, 21);
	printStu(*st);

	char name2[] = "张三";
	setValue(&stu, 2000, name2, 18);
	printStu(stu);
	printf("");

}

在这里插入图片描述

  1. 创建了一个结构体指针st,并申请了空间
  2. 创建了一个结构体变量stu
  3. 试图对stu调用赋值函数,注意本例通过参数不同,区分函数,如同int类型,我们传入stu被视为传入结构体的值,无法修改结构体本身,因此输出函数乱码,如果不加stu.ID赋值,则系统报错未初始化。
  4. 传入结构体指针变量,成功修改所指向的值,其中(*stu)表示指针指向的结构体,stu->可以找的结构体中的变量。
  5. 传入stu的地址,结果同上。

指针使用只需要注意以下几点:

  • 定义变量时(包括函数的参数定义):"*"表示定义指针类型变量,如int *i;
  • 代码执行过程中:变量名表示指针如i;"* 变量名"表示指针指向的类容如* i;"&"表示取地址,如&(*i)同i。int j=0;&j 则是j的地址,**&i则是int指针类型变量i的地址(指针变量的地址/地址的地址)**在函数中想要修改指针变量,也需要传其地址。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值