部分资源图片出自对海贼科技课程的总结
https://www.haizeix.com/
c语言是面向过程的编程范式
一共四种编程范式.面向过程,面向对象,函数式编程,泛型编程
函数是一种映射,
数组是展开的函数,函数是压缩的数组
函数是计算式,数组是计算式.两种方式可以相互转换
深度神经网路可以逼近任何函数
printf
函数
stdio.h
int printf(const char *format, ...);
format:
格式控制字符串scanf
函数
stdio.h
int scanf(const char *format, ...);
format:
格式控制字符串printf
输出一个数字的某一位/*************************************************************************
> File Name: wie.cpp
> Author: ldc
> Mail: litesla
> Created Time: 2018年09月13日 星期四 18时29分42秒
************************************************************************/
#include
#include
using namespace std;
int main(){
//1,2,3int a;
char str[100];
//2,FILE *fp = fopen("/dev/null","w");
//1,2,3scanf("%d", &a);
//1,printf(" %d", printf("%d", a));
//2,fprintf(stdout,"%d", fprintf(fp, "%d",a));
//3,printf("%d\n", sprintf(str,"%d",a));
for (int i = 0,j = 0; i <= 20; i++) {
j += sprintf(str + j,"%d",i);
}
printf("%s",str);
return 0;
}
/*************************************************************************
> File Name: clang_test2.c
> Author: hug
> Mail: [email protected]
> Created Time: 四 9/13 19:13:09 2018
************************************************************************/
#include
int main() {
char str[100];
scanf("%[^\n]s", str);
int n = printf("%s", str);
printf(" has %d chars\n", n);
return 0;
}
% / * (+ -) (& | ^~)
运算符速度从低到高
pow函数说明
pow
函数:指数函数
math.h
double pow(double a, double b);
pow(2,3) = 8
sqrt
函数:开平方数
math.h
double sqrt(double x);
sqrt(16) = 4
ceil向上取整函数
floor
向下取整函数
abs()
整数绝对值函数
fabs
实数绝对值函数
log
以e为底对数函数
log10
以10为底对数函数
acos
函数arccos()
例子:acos(-1) = 3.1415926
/*************************************************************************
> File Name: mysqrt.cpp
> Author: ldc
> Mail: litesla
> Created Time: 2018年09月13日 星期四 20时03分55秒
************************************************************************/
#include
#include
#include
using namespace std;
#define TEST_TIME(func)({\
int begin=clock();\
double ret=func;\
int end=clock();\
printf("%lfms\m",(end-begin) * 1.0/ CLOCK_PER_SEC * 1000);\
})
double _sqrt(double x){
double head = -100,tail = 100, mid;
#define EPS 1e-7
while(tail - head > EPS){
mid=(head + tail)/2.0;
if(mid * mid < x) head = mid;
else tail= mid;
}
#undef EPS
return tail;
}
double f_func(double x,double n){
return x * x - n;
}
double ff_func(double x){
return 2 * x;
}
double newton(int n, double (*f)(double,double), double (*ff)(double)){
double x = 1.0;
#define EPS 1e-7
while(fabs(f(x,n)) > EPS){
x -= f(x,n)/ff(x);
}
#undef EPS
return x;
}
int main(){
int x;
scanf("%d", &x);
printf("%lf\n", _sqrt(x));
printf("%lf\n", newton(x,f_func,ff_func));
return 0;
}
计算机比人勤奋不是比人聪明
==, >=, >, <,<=,!, !=
if
语句
switch
语句:
switch
内部无法定义局部变量
while
,do while
,for
语句
/*************************************************************************
> File Name: fast_read.cpp
> Author: hug
> Mail: [email protected]
> Created Time: 二 9/18 19:48:33 2018
************************************************************************/
#include
using std::cin;
using std::cout;
using std::endl;
char ss[1<<17], *A = ss, *B = ss;
inline char gc() {
return A == B && (B = (A = ss) + fread(ss, 1, 1 << 17, stdin), A == B) ? -1 : *A++;
}
template<typename T> inline void sdf(T &x) {
char c;
T y = 1;
while (c = gc(), (c < 48 || c > 57) && c != -1) {
if (c == '-') y = -1;
}
x = c ^ 48;
while (c = gc(), (c <= 57 && c >= 48)) {
x = (x << 1) + (x << 3) + (c ^ 48);
}
x *= y;
}
int main() {
for (int i = 48; i <= 57; i++) {
printf("%d ^ 48 = %d\n", i, i ^ 48);
}
int n, a;
sdf(n);
for (int i = 0; i < n; i++) {
sdf(a);
}
return 0;
}
函数是压缩的数组,数组是展开的函数
函数会增加程序的可读性
K&R风格函数定义
int is_prime(x)
int x;
{
for (int i = 2; i * i <= x; i++) {
if (x % i == 0) return 0;
}
return 1;
}
程序调用自身的编程技巧叫做递归
才能在遇到难题的时候寻找可行解
[外链图片转存失败(img-SAVc6AFa-1565924120766)(/home/tesla/github/learn/1.C语言/c复习/变参函数.png)]
/*************************************************************************
> File Name: is_prime.c
> Author: hug
> Mail: [email protected]
> Created Time: 四 9/20 19:52:14 2018
************************************************************************/
#include
#include
#include
int is_prime(int x) {
for (int i = 2; i * i <= x; i++) {
if (x % i == 0) return 0;
}
return 1;
}
int max_int(int n, ...) {
va_list arg;
va_start(arg, n);
int ans = INT32_MIN;
for (int i = 0; i < n; i++) {
int temp = va_arg(arg, int);
ans = temp > ans ? temp : ans;
}
return ans;
}
/*************************************************************************
> File Name: 3.my_print.c
> Author: hug
> Mail: [email protected]
> Created Time: 四 9/20 20:26:47 2018
************************************************************************/
#include
#include
#include
#include
int print_int(int x, int flag) {
if (x == 0) {
flag && putchar('0');
return !!(flag);
}
int temp = x, ret = 0, digit = 0;
x = 0;
if (temp < 0) temp = -temp, printf("-");
while (temp) {
x = x * 10 + temp % 10;
temp /= 10;
digit++;
}
while (digit--) {
putchar(x % 10 + '0');
x /= 10;
ret++;
}
return ret;
}
int my_printf(const char *frm, ...) {
int cnt = 0;
va_list arg;
va_start(arg, frm);
for (int i = 0; frm[i]; i++) {
switch (frm[i]) {
case '%' : {
i++;
switch(frm[i]) {
case 'd' : {
int temp = va_arg(arg, int);
int p1 = temp / 10, p2 = temp % 10;
if (temp < 0) {
p1 = -p1, p2 = -p2;
putchar('-'); cnt++;
}
cnt += print_int(p1, 0);
cnt += print_int(p2, 1);
} break;
default :
fprintf(stderr, "error : unknow %%%c\n", frm[i]);
exit(1);
}
} break;
default:
putchar(frm[i]);
cnt++;
}
}
return cnt;
}
int main() {
int n = 123;
my_printf("hello world\n");
my_printf("n = %d\n", n);
my_printf("n = %d\n", 12000);
my_printf("n = %d\n", 0);
my_printf("n = %d\n", -567);
my_printf("n = %d\n", INT32_MAX);
my_printf("n = %d\n", INT32_MIN);
return 0;
}
数组是一片连续的存储空间
元素存在递推关系的化用数组存储比较号
函数是压缩的数组
素数筛
折半查找
/*************************************************************************
> File Name: binary_search.cpp
> Author: ldc
> Mail: litesla
> Created Time: 2018年09月23日 星期日 10时41分54秒
************************************************************************/
#include
using namespace std;
int binary_search(int (*arr)(int), int x, int n){
int head = 0,tail = n - 1;
while(head <= tail){
int mid = (head + tail) >> 1;
if(arr(mid) == x) return mid;
else if (arr(mid) < x) head = mid + 1;
else tail = mid - 1;
}
return -1;
}
int main(){
int arr[100];
char *p1 = (char * )(arr + 1);
char *p2 = (char * )(arr + 2);
long long * p3 = (long long *)(arr + 1);
p1[0] = 'a';
p1[1] = 'b';
p1[2] = 'c';
p1[3] = 'd';
for(int i = 0; i < 3; i++) p2[i] = p1[i];
printf("p1 = %s, p1 = %lx\n", p1 ,*(long long*)p1);
//printf("p3 = %ld",*p3);
return 0;
}
/*
int main(){
char arr[100];
int *p1 = (int *)(arr + 1);
int *p2 = (int *)(arr + 2);
*p1 = 1;
*p2 = 2;
printf("*p1 = %d\n*p2 = %d\n", *p1, *p2);
}*/
/*
int main(){
int ret;
unsigned char * p = (unsigned char *)&ret;
int a,b,c,d;
scanf("%d%d%d%d",&a, &b, &d, &d);
p[0] = a;
p[1] = b;
p[2] = c;
p[3] = d;
//p[0] = d;
//p[1] = c;
//p[2] = b;
//p[3] = a;
//注意高对高,低对低
printf("ret: %u\n", ret);
return 0;
}*/
编译器预定义的宏
__DATA__
__TIME__
__LINE__
__func__
__FUNC__
........
/*************************************************************************
> File Name: max.cpp
> Author: ldc
> Mail: litesla
> Created Time: 2018年09月23日 星期日 11时59分24秒
************************************************************************/
#include
using namespace std;
#define P(func) {\
printf("%s = %d\n", #func, func); \
}
//#define MAX(a,b) ((a) > (b) ? (a) : (b))
#define MAX(a,b) ({\
__typeof(a) aa = (a);\
__typeof(b) bb = (b);\
aa > bb ? aa : bb;\
})
int main(){
//P(MAX(2,3));
//P(5 + MAX(2,3));
//P(MAX(2,MAX(3,4)));
//P(MAX(2,3 > 4 ? 3 : 4));
int a = 7;
P(MAX(a++,6));
printf("a = %d\n", a);
( {int a = 3;});
printf("a = %d\n",a);
return 0;
}
[外链图片转存失败(img-ONrhS24B-1565924120767)(/home/tesla/github/learn/1.C语言/条件编译.png)]
/*************************************************************************
> File Name: 4.define.cpp
> Author: hug
> Mail: [email protected]
> Created Time: 日 9/23 11:38:10 2018
************************************************************************/
#include
using std::cin;
using std::cout;
using std::endl;
#ifdef DEBUG
#define P printf("%s : %d\n", __PRETTY_FUNCTION__, __LINE__)
#else
#define P
#endif
void testfunc() {
P;
}
int main() {
printf("%s %s\n", __DATE__, __TIME__);
P;
testfunc();
return 0;
}
可以通过预编译命令进行调整 (这么做是为了效率)
一个共用体类型占用空间的大小是他里面存储的最大的数据类型
/*************************************************************************
> File Name: ip.cpp
> Author: ldc
> Mail: litesla
> Created Time: 2018年10月04日 星期四 10时04分05秒
************************************************************************/
#include
#include
using namespace std;
union IP{
struct{
unsigned char arr[4];
}ip;
unsigned int num;
};
int main(){
int a,b,c,d;
IP ip;
while(scanf("%d.%d.%d.%d",&a, &b, &c, &d) != EOF){
ip.ip.arr[0] = a;
ip.ip.arr[1] = b;
ip.ip.arr[2] = c;
ip.ip.arr[3] = d;
printf("%u\n", ip.num);
// memset(&ip,'\0',sizeof(ip));
}
return 0;
}
struct test{
short a;//占用两个字节只能放在距离开始位置偶数个距离的地方
char b;//占用一个字节,有个空就能差
int c;//占用四个字节,只能放在距离开始位置4个字节的地方
double e;//....
}
信息本身没有改变关键是你怎么取看待他
/*************************************************************************
> File Name: 6.struct&union.cpp
> Author: hug
> Mail: [email protected]
> Created Time: 四 10/ 4 10:17:06 2018
************************************************************************/
#include
#include
#include
struct person {
char name[20];
int age;
char gender;
float height;
};
struct test {
char b;
short a;
int c;
double e;
};
struct Number {
int type; // 0->int or 1->double
union {
int num1;
float num2;
} N;
};
void print(Number *n) {
switch (n->type) {
case 0: printf("%d\n", n->N.num1); break;
case 1: printf("%f\n", n->N.num2); break;
}
return ;
}
void set(Number *n, float num) {
n->type = 1;
n->N.num2 = num;
}
void set(Number *n, int num) {
n->type = 0;
n->N.num1 = num;
}
int main() {
srand(time(0));
struct test a;
printf("sizeof(person) : %d\n", sizeof(struct person));
printf("%p %p %p", &a.a, &a.b, &a.c);
#define MAX_N 20
Number arr[MAX_N];
for (int i = 0; i < MAX_N; i++) {
int op = rand() % 2;
switch (op) {
case 0: {
int value = rand() % 100;
set(arr + i, value);
} break;
case 1: {
float value = (1.0 * (rand() % 10000) / 10000) * 100;
set(arr + i, value);
} break;
}
}
for (int i = 0; i < MAX_N; i++) {
print(arr + i);
}
arr[0].N.num2 = 1.0;
printf("arr[0].N.num1 = %d\n", arr[0].N.num1);
printf("arr[0].N.num1 = %x\n", arr[0].N.num1);
return 0;
}
指针变量存储的是变量的首地址
指针变量也是变量,也有地址
重点概念
等价形式交换
*p = a
p + 1 = &p[1]
p->filed = (*p).filed = a.filed
int (*add)(int, int);//变量
typedef int (*add)(int,int);//类型
指针的解析
[外链图片转存失败(img-IlFsvrEc-1565924120768)(/home/tesla/github/learn/1.C语言/指针的解析.png)]
[外链图片转存失败(img-Nxk6vkwt-1565924120768)(/home/tesla/github/learn/1.C语言/指针的解析2.png)]
c语法在进行语法检查的时候是看函数指针的类型的参数列表,和你调用的类型对不对的上,对于你之前是那个函数他不管
是有参数的
int main(int argc, char *argv[], char *env[])
argc
标记的是有几个argv
env
标记结束的方式是最后一个位置指向一个空地址
取得环境变量的作用适应不同的系统或者环境
/*************************************************************************
> File Name: test.h
> Author: ldc
> Mail:
> Created Time: 2018年10月05日 星期五 15时17分05秒
************************************************************************/
#ifndef _TEST_H
#define _TEST_H
#include
//测试结构体
struct TestFuncData{
int total, expect;
//总量和成功量
};
//声明一个函数指针传递的参数是,链表节点
typedef void (*test_func_t)(struct TestFuncData *);
//链表节点
struct FuncData {
const char *a_str, *b_str;//函数名
test_func_t func;//函数指针
struct FuncData *next;//链表指针
};
//增加链表节点的函数,参数有函数名,和需要测试的函数指针
void addFuncData(const char *a, const char *b, test_func_t func);
//声明一个函数
int RUN_ALL_TEST();
//声明一个函数
//__attribute__让下面那个函数比主函数先运行
//生成一个增加函数
//函数内部调用增加链表节点函数
//1讨论为什么要在函数内部调用那个函数,
//因为测试是多种函数一起编译,这样就可以重复的调用addFuncData
//最后一行生成一个函数头,注意函数的参数是测试结构体
//注意这个是多行宏定义
#define TEST(a,b) \
void a##_haizeix_##b(struct TestFuncData *); \
__attribute__((constructor)) \
void ADDFUNC_##a##_haizeix_##b() { \
addFuncData(#a, #b, a##_haizeix_##b); \
} \
void a##_haizeix_##b(struct TestFuncData *__data)
//判断该是否相等,ret是局部变量
//注意最外面有()
#define EXPECT_EQ(a, b) ({ \
int ret; \
printf("%s == %s %s\n", #a, #b, (ret = (a == b)) ? "True" : "False"); \
__data->total += 1; \
__data->expect += ret; \
})
#define EXPECT_GT(a, b) ({ \
int ret; \
printf("%s > %s %s\n", #a, #b, (ret = (a > b)) ? "True" : "False"); \
__data->total += 1; \
__data->expect += ret; \
})
#define EXPECT_LT(a, b) ({ \
int ret; \
printf("%s < %s %s\n", #a, #b, (ret = (a < b)) ? "True" : "False"); \
__data->total += 1; \
__data->expect += ret; \
})
#define EXPECT_NE(a, b) ({ \
int ret; \
printf("%s != %s %s\n", #a, #b, (ret = (a != b)) ? "True" : "False"); \
__data->total += 1; \
__data->expect += ret; \
})
#define EXPECT_GE(a, b) ({ \
int ret; \
printf("%s >= %s %s\n", #a, #b, (ret = (a >= b)) ? "True" : "False"); \
__data->total += 1; \
__data->expect += ret; \
})
#define EXPECT_LE(a, b) ({ \
int ret; \
printf("%s <= %s %s\n", #a, #b, (ret = (a <= b)) ? "True" : "False"); \
__data->total += 1; \
__data->expect += ret; \
})
#endif
/*************************************************************************
> File Name: test.c
> Author: ldc
> Mail:
> Created Time: 2018年10月05日 星期五 15时16分21秒
************************************************************************/
#include
#include "test.h"
//链表头部
static struct FuncData *FuncData_head = NULL;
//增加链表节点函数,头插法
void addFuncData(const char *a, const char *b, test_func_t func) {
struct FuncData *p = (struct FuncData *)malloc(sizeof(struct FuncData));
p->a_str = a;
p->b_str = b;
p->func = func;
p->next = FuncData_head;
FuncData_head = p;
return ;
}
int RUN_ALL_TEST() {
struct FuncData *current_node, *next_node;
if (FuncData_head == NULL) return 0;
current_node = FuncData_head->next;
FuncData_head->next = NULL;
//链表逆序
while (current_node != NULL) {
next_node = current_node->next;
current_node->next = FuncData_head;
FuncData_head = current_node;
current_node = next_node;
}
//三种不同测试结果的输出样式
char color[3][100] = {
"[ \033[1;32m%.2lf%%\033[0m ] total : %d,expect : %d\n",
"[ \033[0;31m%.2lf%%\033[0m ] total : %d,expect : %d\n",
"[ \033[1;31m%.2lf%%\033[0m ] total : %d,expect : %d\n"};
//遍历链表,并且处理每个节点信息
for (struct FuncData *p = FuncData_head; p; p = p->next) {
printf("[%s, %s]\n", p->a_str, p->b_str);
struct TestFuncData data = {0, 0};
p->func(&data);
double rate = 1.0 * data.expect / data.total * 100;
int index = 0;
if (rate < 100) index = 1;
if (rate < 50) index = 2;
printf(color[index], rate, data.total, data.expect);
}
return 0;
}
/*************************************************************************
> File Name: text.cpp
> Author: ldc
> Mail: litesla
> Created Time: 2018年10月04日 星期四 17时52分37秒
************************************************************************/
#include
#include "test.h"
int add(int a, int b) {
return a + b;
}
int is_prime(int x) {
if (x <= 1) return 0;
for (int i = 2; i * i <= x; i++) {
if (x % i == 0) return 0;
}
return 1;
}
TEST(test, is_prime_func) {
EXPECT(is_prime(2), 0);
EXPECT(is_prime(-2), 0);
EXPECT(is_prime(15), 0);
EXPECT(is_prime(9973), 1);
}
TEST(test, add_func) {
EXPECT(add(1, 2), 3);
EXPECT(add(3, 4), 7);
EXPECT(add(2, 2), 4);
}
int main() {
return RUN_ALL_TEST();
}
[外链图片转存失败(img-FV8UIOtT-1565924120769)(/home/tesla/github/learn/1.C语言/c复习/test测试结果.png)]