项目12交换机后台管理之端口管理的再次优化
项目精讲
1.为什么要使用指针
函数的值传递,无法通过调用函数,来修改函数的实参。
2.指针定义
指针是什么
指针本质是一个地址值:
#include <stdio.h>
int main(void){
int age;
//定义了一个指针
//指针是一个变量
//这个变量的名称是 p
//这个指针,可以用来指向一个整数!
//就是说:p的值是一个整数的地址!!!
int * p;
//指针p指向了age
//p的值,就是变量age的地址
p = &age;
scanf("%d", p);
printf("age=%d\n", age);
return 0;
}
指针的定义
int p;
或者:
int p;
或者:
int * p;
c语言中的指针,占用4个字节。
3.指针的初始化、访问
指针的初始化
demo:
#include <stdio.h>
int main(void) {
int mygirl = 18;
int *p1 = &mygirl;
int *p2 = p1;
return 0;
}
指针的访问
访问指针
demo
#include <stdio.h>
int main(void) {
int mygirl = 18;
int *p1 = &mygirl;
int *p2 = p1;
//1. 访问(读、写)指针变量本身的值!!!(和其他普通变量的访问方式相同)
int *p3;
p3 = p1; //读指针p1的值, 设置指针p3的值
printf("p1=%d\n", p1); //不建议使用该方式
//使用16进制打印,把地址值当成一个无符号数来处理的
printf("p1=0x%p\n", p1);
printf("p1=0x%x\n", p1);
printf("p1=0x%X\n", p1);
return 0;
}
2进制与16进制(补充)
10进制,2进制,16进制
10进制:
每一位,有10种状态(0,1,2,3,4,5,6,7,8,9),逢10进1
2进制:
计算机只识别2进制
每一位,有2种状态(0,1)
16进制:
每一位,有16种状态(0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f)
为了描述方便,我们常常把一些二进制数据,转换为16进制表示
比如:
10进制:257
二进制:100000001
16进制:0x101
访问指针所指向的内容
#include <stdio.h>
int main(void) {
int my_girl = 18;
int *p = &my_girl;
int x;
x = *p; //*是一个特殊的运算符,*p表示读取指针p所指向的变量的值
printf("x=%d\n", x);
printf("*p = %d\n", *p);
my_girl++;
printf("*p = %d\n", *p);
return 0;
}
4.空指针
1.什么是空指针?
空指针,就是值为0的指针。
int *p;
p = 0;
2.访问空指针的后果
#include <stdio.h>
int main(void) {
int *p;
p = 0; //p就是一个空指针!
printf("%p\n", p);
//访问空指针指向的值,将导致程序崩溃!!!
printf("%d\n", *p); //读取 地址为0的int类型变量
system("pause");
printf("程序结束\n");
return 0;
}
3.空指针的使用
1)指针初始化为空指针
例如: int p = 0;
建议这样使用:
int p = NULL;
目的就是,避免访问非法数据。
2)指针不再使用时,可以设置为空指针
int *my_girl = &xiao_long_lv;
my_girl = NULL;
1)表示这个指针还没有具体的指向
int *p = NULL;
if (!p) {
......
}
5.指向结构体的指针
#include <stdio.h>
struct friend {
char name[32];
char sex[3];
int age;
};
int main(void) {
struct friend f1 = {
"小龙女", "女", 18
};
//定义了一个指针变量p,
//这个my_girl可以指向一个struct friend类型的变量
struct friend *my_girl;
my_girl = &f1;
//直接通过结构体变量来访问该结构体内部的成员
printf("%s, %s, %d\n", f1.name, f1.sex, f1.age);
//通过指针p来访问结构体内部的成员
//方式1, 很少使用该方式
printf("%s, %s, %d\n", (*my_girl).name, (*my_girl).sex, (*my_girl).age);
//方式2
printf("%s, %s, %d\n", my_girl->name, my_girl->sex, my_girl->age);
return 0;
}
6.字符的算术运算
指针的自增运算
#include <stdio.h>
int main(void) {
int ages[] = {20,15,16,14,23,28,30,38, 35, 32, 26};
int len = sizeof(ages) / sizeof(ages[0]);
//先使用数组的方式来访问
for (int i=0; i<len ; i++) {
printf("第%d个学员的年龄是:%d\n", i+1, ages[i]);
}
//使用指针来访问
//int *p = ages; //指针p指向ages[0]
int i = 0;
for (int *p = ages; p < ages+len ; p++, i++) {
printf("第%d个学员的年龄是:%d\n", i+1, *p);
}
return 0;
}
指针的自减运算
#include <stdio.h>
#include <string.h>
/**
* 让用户输入一个字符串,然后反向输出(不能改变原来的字符串!)
* "12345" 逆转成 "54321"
*/
int main(void) {
char line[128];
int len;
char tmp;
printf("请输入一个字符串: ");
gets(line);
len = strlen(line);
//方法1 (改变了字符串本身)
/*
for (int i=0; i<len/2; i++) {
tmp = line[i];
line[i] = line[len-1-i];
line[len-1-i] = tmp;
}
printf("逆转以后:%s\n", line);
*/
//方法2:不改变字符串
/*
for (int i=len-1; i>=0; i--) {
printf("%c", line[i]);
}
*/
//用指针来重写方法2
char *p1 = line;
char *p2 = p1 + len -1;
for (char *p=p2; p>=p1; p--) { //p--,就相当于: p=p-1
printf("%c", *p);
}
return 0;
}
指针与整数之间的加减运算
指针与指针之间的加减运算
7.空指针
良好的编码习惯:使用空指针
8.指向数组的指针
项目需求
使用指针进一步优化端口管理,使代码更简明。
项目实现
项目练习
1.实现含有中文字符的字符串逆转
void reverse(unsigned char *s) {
int len = strlen(s);
unsigned char tmp[len+1];
unsigned char *p1 = s;
unsigned char *p2 = tmp + len;
*p2-- = 0;
while (*p1) {
if (*p1 < 0xA0) { //ASCII字符,一般都是小于等于127的。
*p2-- = *p1++;
} else {
*(p2-1) = *p1++;
*p2 = *p1++;
p2 -= 2;
}
}
for (int i=0; i<len; i++) {
s[i] = tmp[i];
}
}