函数指针
作用:利用函数指针,可以动态的调用函数;
格式:返回类型 (*指针名)(形参列表)
void function()
{
printf("run the %s,%s,%d\n",__FUNCTION__,__FILE__,__LINE__);//日志打印
}
int function2(int num1,int num2)
{
printf("run the %s,%s,%d\n",__FUNCTION__,__FILE__,__LINE__);//日志打印 函数名、文件、所在行编号
return num1+num2;//返回入参中两个数值和
}
int main()
{
//函数指针
int (*p_fun)(int,int) = function2;
void (*p1_fun)(void) = function;
int sum = p_fun(5,10);
p1_fun();
}
int add(int a,int b)
{
return a+b;
}
int sub(int a,int b)
{
return a-b;
}
int mul(int a,int b)
{
return a*b;
}
int div(int a,int b)
{
return a/b;
}
int main()
{
int (*p_calc[4])(int,int) = {add,sub,mul,div};//函数指针数组
printf("请输入两个数字参与计算:\n");
int a = 0;
int b = 0;
scanf("%d %d",&a,&b);
printf("请输入你要进行的操作:\n");
printf("0:加法 1:减法 2:乘法 3:除法\n");
int op = 0;
scanf("%d",&op);
if (op < 0 || op > 3)
{
printf("输入错误,请重新输入\n");
return -1;
}
int res = p_calc[op](a,b);
printf("the result is %d\n",res);
}
字符串
在C语言中,处理字符串通常涉及到使用字符数组(char 数组),字符串:定义可以使用双引号引起来的;字符串结束标志'\0';
字符串使用依赖标准库(头文件)<string.h>
常见字符串命令(比较、替换、截取、查找、切割、检索、加密、打乱内容、大小写转换):
strcpy, strcat, strlen, strcmp 等
字符串定义方式:
char str[4+1] = “abcd”; //数组:内容长度+结束符’\0’
char *str = “abcd”; //指针,存放在只读区内,不可以修改
void stringTest()
{
//字符串的定义 利用字符数组+双引号的方式定义字符串
char str[4+1] = "abcd";//4个字符(字符串长度小于等于4)+1个结束符;字符串长度等于数组长度的时候可能存储不完全
//字符串的定义 利用字符指针+双引号的方式定义字符串
char* str1 = "abcd";//会把字符数组放在只读区,不能修改;里面定义的字符串是可以复用的
char* str2 = "abcd";//在创建abcd字符串的时候,str1和str2指向同一块内存区域
//在创建ABCD的时候,会检查只读区是否有相同的字符串,如果有就直接指向同一块内存区域,如果没有就创建一块新的内存区域
printf("the string is %s\n",str);
printf("the string is %s\n",str1);
printf("%p\n",str1);
printf("%p\n",str2);
}
字符输入
int stringScanf()
{
char str[20] = {0};
printf("请输入一个字符串:\n");
scanf("%s",str);
if (strlen(str) > (sizeof(str)-1)) //判断输入字符串长度是否大于字符串数组允许输入的最大值
{
printf("输入的字符串长度超过20个字符,请重新输入\n");
return -1;
}
printf("the string is %s\n",str);
return 0;
}
字符串输入及使用指针遍历
void stringScanf1()
{
char str[20] = {0};
printf("请输入一个字符串:\n");
scanf("%s",str);//scanf函数会自动添加结束符'\0',所以不需要手动添加
if (strlen(str) > (sizeof(str)-1))//判断字符串长度是否超过20个字符
{
printf("输入的字符串长度超过20个字符,请重新输入\n");
return;
}
char* p = str;
//利用指针遍历字符串
printf("the string is :");
while(1)
{
if (*p == '\0') //字符串结束标志
{
break;
}
printf("%c",*p);
p++;
}
printf("\n");
}
字符串数组
void stringarr()
{
char arrstr[5][20] = {"hello","world","nihao","zhongguo","shijie"};
for(int i = 0;i < 5;i++)
{
printf("the string is %s\n",arrstr[i]);//利用数组下标遍历二维数组
}
char* p = arrstr[0];
for(int i = 0;i < 5;i++)
{
printf("the string is %s\n",p);
p += 20;//每次移动20个字节,二维数组中的每个字符串长度为20,利用指针加法遍历二维数组
}
for(int i = 0;i < 5;i++)
{
p = arrstr[i];//利用指针遍历二维数组,指针每次获取二维数组中的一个字符串
printf("the string is %s\n",p);
}
//把五个字符串的指针放到一个数组中,指针数组
char* p_arr[5] = {"hello","world","nihao","zhongguo","shijie"};
for(int i = 0;i < 5;i++)
{
printf("the string is %s\n",p_arr[i]);
}
}
字符串常见函数
常见string函数strlen(长度)、strcpy(复制)、strcat(拼接)、strcmp(比较)
#include <stdio.h>
#include <string.h>
void stringFunction()
{
//常见string函数strlen(长度)、strcpy(复制)、strcat(拼接)、strcmp(比较)、strchr、strstr、strlwr(转小写)、strupr(转大写)
char* str = "hello world";//字符串常量,存放在只读区
char str1[20] = "abcd"; //字符串数组,存放在栈区
char str2[20] = "hello";
printf("the string length is %lu\n",strlen(str));
printf("the string length is %lu\n",strlen(str1));
printf("the string length is %lu\n",strlen(str2));
/*strcat把第二字符串的全部的内容,拷贝到第一个字符串的末尾
1.第一个字符串是需要可以修改的(可写的)
2.第一个字符串中的剩余空间可以容纳拼接的字符串*/
strcat(str1,str2);//拼接字符串
printf("the string is %s\n",str1);
printf("the string is %s\n",str2);
/*strcpy:把第二个字符串中的全部内容,拷贝到第一个字符串中,把第一个字符串里面的原始内容给覆盖了
1.第一个字符串是需要可以修改的(可写的)
2.第一个字符串中的剩余空间可以第二个的字符串全部内容*/
strcpy(str1,str2);//复制字符串
printf("the string is %s\n",str1);
printf("the string is %s\n",str2);
/*strcmp:比较两个字符串;在比较的时候要求顺序和内容一致,才能返回0
1.如果第一个字符串大于第二个字符串,返回正数
2.如果第一个字符串小于第二个字符串,返回负数
3.如果两个字符串相等,返回0*/
int res = strcmp(str1,str2);
if (res > 0)
{
printf("the string %s is greater than %s\n",str1,str2);
}
else if (res < 0)
{
printf("the string %s is less than %s\n",str1,str2);
}
else
{
printf("the string %s is equal to %s\n",str1,str2);
}
/*strlwr*/
//strlwr(str1);//把字符串转换成小写
//printf("the string is %s\n",str1);
/*strupr*/
//strupr(str1);//把字符串转换成大写
//printf("the string is %s\n",str1);
}
使用 strlen 函数获取字符串的长度(不包括结尾的空字符)。
#include <stdio.h>
#include <string.h> // 包含strlen的声明
int main()
{
char str[] = "Hello, world!";
int length = strlen(str); // 获取字符串长度
printf("Length of '%s' is %d.\n", str, length);
return 0;
}
使用strcpy复制字符串内容
#include <stdio.h>
#include <string.h>
int main()
{
char str1[] = "Hello, world!"; // 初始化字符串
char str2[50]; // 定义一个足够大的字符数组来存储字符串
// 使用strcpy复制字符串
strcpy(str2, str1); // 将str1的内容复制到str2
printf("str1: %s\n", str1);
printf("str2: %s\n", str2);
return 0;
}
使用 strcat 函数可以将两个字符串连接起来。
#include <stdio.h>
#include <string.h> // 包含strcat的声明
int main()
{
char str1[50] = "Hello, ";
char str2[] = "world!";
char str3[100]; // 确保有足够的空间存储结果
// 使用strcat连接字符串
strcat(str1, str2); // 将str2连接到str1的末尾
strcpy(str3, str1); // 可以选择复制回str3以保留原始str1内容
printf("Combined string: %s\n", str1);
return 0;
}
使用 strcmp 函数比较两个字符串。这个函数返回0如果两个字符串相等,返回负值如果第一个字符串在字典序上小于第二个,返回正值如果第一个字符串在字典序上大于第二个;
#include <stdio.h>
#include <string.h> // 包含strcmp的声明
int main()
{
char str1[] = "Hello";
char str2[] = "World";
char str3[] = "Hello";
int result;
result = strcmp(str1, str2); // 比较str1和str2
if (result == 0) {
printf("str1 and str2 are equal.\n");
} else if (result < 0) {
printf("str1 is less than str2.\n");
} else {
printf("str1 is greater than str2.\n");
}
result = strcmp(str1, str3); // 比较str1和str3,两者相等,应返回0
if (result == 0) {
printf("str1 and str3 are equal.\n"); // 应输出此行信息
} else {
printf("str1 is not equal to str3.\n"); // 不应输出此行信息,除非有错误或特殊情况发生。正常情况下不会执行到这里。
}
return 0;
}
利用字符实现用户、密码登录功能(demo)
实际上用户相关信息在数据库中都需要加密存储(用户安全隐私合规),用户相关信息不能进行明文存储;
使用到C语言相关知识:函数、指针、结构体(结构体起别名、结构体初始化、使用指针实现结构体访问)、字符串(只读、输入、字符串长度、字符串比较)、字符数组、for、if break、continue等
typedef struct user
{
char username[20];
char password[20];
}user_t;
void userLogin(user_t* p_user)
{
char *username = "zhangtao";
char *password = "Cxm940521";
for(int i = 0;i < 5;i++)
{
printf("请输入用户名,长度20字符以内:\n");
scanf("%s",p_user->username);
if (strlen(p_user->username) > 20)
{
printf("用户名长度超过20个字符,请重新输入\n");
continue;
}
printf("请输入密码(长度20字符以内,大写,小写,数字)\n");
scanf("%s",p_user->password);
if (strlen(p_user->username) > 20 || strlen(p_user->password) > 20)
{
printf("用户名或密码长度超过20个字符,请重新输入\n");
continue;
}
if (strcmp(username,p_user->username) == 0 && strcmp(password,p_user->password) == 0)
{
printf("登录成功\n");
break;
}
else
{
printf("登录失败,剩余 次%d\n",5-i);
continue;
}
}
}
结构体
结构体(Structures)是一种复合数据类型,允许将多个不同类型的数据项组合成一个单一的类型;
结构体可以理解为自定义的数据类型 ,由一批数据组合而成的结构型数据,里面的每一个数据都是结构体的成员;
结构体的定义方式
struct human//定义结构体
{
char name[20];
int age;
float height;
float weight;
};
void printHuman()
{
struct human h1; //定义human结构体h1
//初始化结构体h1内容
h1.age = 10;
h1.height = 1.75f;
h1.weight = 60.0f;
strcpy(h1.name,"zhangsan");//字符串(数组)初始化使用strcpy
//打印结构体结构体内容
printf("the name is %s\n",h1.name);
printf("the age is %d\n",h1.age);
printf("the height is %f\n",h1.height);
printf("the weight is %f\n",h1.weight);
}
typedef struct //上面的名称可以有,也可以省略
{
char name[20];
int age;
}student_t; //结构体别名,后缀_t
void changeStudent(student_t* p_student)//定义结构体指针p_student
{
//使用结构体指针访问结构体,
strcpy(p_student->name,"lisi");
p_student->age = 20;
//结构体信息打印
printf("the name is %s\n",p_student->name);
printf("the age is %d\n",p_student->age);
}
结构体在嵌入式中注意事项(内存相关)
内存分布:
确定变量位置:只能放在自己类型数据整数倍的内存地址上;
最后一个补位:结构体的总大小,是最大类型的数据的整数倍;
常见定义方式:先定义占用内存空间少的成员,在定义占用内存空间多的成员;
typedef struct number
{
double a;//0-7
char b;//8
int c;//12-15
char d;//16 补位对齐值23;总长度24字节,起始字节为0
}number_t;
typedef struct
{
double a;//0-7
char b;//8
char d;//9
int c;//12-15
}number1_t;
int main()
{
number_t num;
number1_t num1;
printf("the size of number_t is %lu\n",sizeof(num));//占用24字节
printf("the size of number_t is %lu\n",sizeof(num1));//占用16字节
}
/*思考一下为什么*/
1588

被折叠的 条评论
为什么被折叠?



