前言
C语言最奇葩的两种指针变量类型:行指针和函数指针
int (*p)[12] = 二维数组;
int (*p)(int a,double d) = 函数名;
1、qsort
简介:void qsort (void* base, size_t num, size_t size, int (compar)(const void,const void*));
a)可以用于各种结构体内部的成员作为排序规则的快速排序。
b)因为它不知道你是啥结构体,所以第一个参数是void*,并且收集你的结构体特征。
c)特征包括每块结构体的大小,总共有多少块。
d)回调函数的应用
#include <stdio.h> /* printf */
#include <stdlib.h> /* qsort */
int values[] = { 40, 10, 100, 90, 20, 25 };
int compare(const void* a, const void* b)
{
return (*(int*)a - *(int*)b);
}
//void qsort (void* base, size_t num, size_t size,int (*compar)(const void*,const void*));
int main()
{
int n;
qsort(values, _countof(values), sizeof(*values), compare); //前面是个数 后面是单价
for (n = 0; n < _countof(values); n++)
printf("%d ", values[n]);
return 0;
}
2、一级指针变量的取地址与不取地址
double d = 888;
double a[28] = {888.88,999.99};
double* p = &d;//对单个普通变量取地址
p = a;//普通一维数组不取地址
3、数组指针(行指针)的取与不取地址:
char sName[20];
double a[5][12];
char(*p)[20] = &sName;//单个一维数组取地址 char[20] *p;
double(*q)[12] = a;//多个一维数组的不取地址
4、二级指针变量的取与不取地址:
double p = NULL;
double ps[20] = {NULL};
double pp = &p;//单个一级指针变量取地址double* 的地址就是double**
pp = ps;//多个一级指针变量的数组不取地址
5、二级指针变量的应用:
a)主要对指针数组进行遍历;
b)做输出参数对单个一级指针的实参修改;
DOS参数的含义:
a)一个是指针变量的个数,一个是指针数组的地址;
b)可以对每个字符串指针指向的底层内容整理,形成外部数据的传入方式。
c)在VS中可以设置模拟传入数据,然后设置断点来观测;
一、函数指针
/*
array-pointer(line-pointer)数组指针(行指针)二维数组
pointer-array:指针数组(二级指针)
function-array:函数指针
*/
#include<stdio.h>
int add(int a, int b)
{
return a + b;
}
int dec(int a, int b)
{
return a - b;
}
int mult(int a, int b)
{
return a * b;
}
void Test(double d)
{
}
int main()
{ //右值dec称之为函数指针常量(函数地址)
// auto p = dec; //C++11 auto 自动识别类型 左值的指针变量称之为函数指针变量
int (*p)(int a, int b) = NULL; //定义类似行指针
p = mult; //p指向那个函数就可以调用那个函数 (前提 类型相同)
int n = (*p)(88, 99);
p = dec;
int m = (*p)(100, 2); //函数指针变量的底层就是一个函数
int c = p(12, 11);// 简易调用
printf("m=%d n=%d c=%d\n", m, n, c);
int(*p[8])(int,int); //函数指针变量数组
//p = Test;
return 0;
}
typedf 别名使用
//int(*FUNC_PTR)(int, int);本来是全局变量 加上typedef变成类型了 可以用这个类型来定义p1,p2,p3
typedef int(*FUNC_PTR)(int, int);
FUNC_PTR p1, p2, p3;
int main()
{
FUNC_PTR a[8];
return 0;
}
二、四则计算器项目
完成四则计算器项目:
对用户在DOS参数中输入的 左右数据和计算符号分离成3个部分,区别不同计算符号进行己算并打印结果
代码如下(示例):
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
//int main(int argc, char* argv[] )
int main(int argc, char** argv)
{
if (argc<2) //输入不够
{
puts("支持[+-*/]命令格式:cala 88.88-66.6");
return -1;
}
/* 下标法
char s[256];
s[0] = 0;
int i = 0; //先strcpy再做几次strcat
while (++i<argc) //循环3次 1.2.3
{
strcat(s, argv[i]);
}*/
char s[256];
s[0] = 0;
while (*++argv)
strcat(s, *argv);
char* p = strpbrk(s, "+-*/"); //多字符查找 进行拆分
if (!p) //不是+-*/则提示
{
puts("支持[+-*/]命令格式:cala 88.88-66.6");
return -1;
}
char c = *p; //+ p的位置
*p++ = '\0';
double left=atof(s), right=atof(p),result =0.0; //atof
switch (c)
{
case '+':
result = left + right;
break;
case '-':
result = left - right;
break;
case '*':
result = left * right;
break;
case '/':
result = left / right;
break;
default:
break;
}
printf("%g %c %g = %g\n",left ,c,right,result);
return 0;
}
指针数组的遍历
while (--argc)
strcat(s, *++argv); //指针法
while (*++argv)//遇到空指针结束
strcat(s, *argv);