/*******************************************************
*
- goto 语句总结:
-
1. 用于对程序跳转资源释放,不能直接结束;
-
2. 深度循环退出,使用 break、continue 不便;
-
3. 不可以跨函数使用(局部变量);
- 函数:
-
内置函数:使用static修饰的函数,只能在本文件中使用;
-
外部函数:使用extern修饰的函数,使用时在本文件中要声明不定义;
-
内联函数是指用inline关键字修饰的函数。在类内定义的函数被默认成内联函数。
-
内联函数从源代码层看,有函数的结构,而在编译后,却不具备函数的性质。
-
内联扩展是用来消除函数调用时的时间开销。它通常用于频繁执行的函数,对于小内存空间的函数非常受益。
-
使用内联函数的时候要注意:
-
递归函数不能定义为内联函数
-
内联函数一般适合于不存在while和switch等复杂的结构且只有1~5条语句的小函数上,否则编译系统将该函数视为普通函数。
-
内联函数只能先定义后使用,否则编译系统也会把它认为是普通函数。
-
对内联函数不能进行异常的接口声明。
- 变量:定义位置(函数内<局部>,函数外<全局> , 函数内外之间< 形参 >)
-
1. 全局变量:全局存储区,静态区,静态存储单元;
-
2. 局部变量:保存在栈区,函数被调用时才动态分配;
-
3. 初始化:局部变量定义时不会被编译器自动初始化,全局变量会*
-
* int 0 *
-
* char '\0' *
-
* float 0 *
-
* double 0 *
-
* pointer NULL *
- 数组:
-
1.多维数组在空间上还是一维分布;
-
2.数组作为形参传递给函数【char】
-
a. char * arr;
-
b. char arr[10];
-
c. char arr[];
-
一般可以把长度传入,同时可以用长度防止访问越界;
- 枚举:4个字节,常用于switch语句;
- 指针:
-
作为函数返回值时,防止返回栈变量的地址;
-
运算:++ -- + - < >
-
ptr+1 运算后的结果与指针指向类型相关,单位为指向数据类型的单位;
-
char * p1 = 0x100;
-
* short * p2 = 0x100; *
-
* int * p3 = 0x100; *
-
* float * p4 = 0x100; *
-
* double * p5 = 0x100; *
-
* printf("%p\n", (p1+1)); 0x101 *
-
* printf("%p\n", (p2+1)); 0x102 *
-
* printf("%p\n", (p3+1)); 0x104 *
-
* printf("%p\n", (p4+1)); 0x104 *
-
* printf("%p\n", (p5+1)); 0x108 *
- 函数指针:
- int (* p)(int ,int);
-
int (* p)(int ,int) = &max; //此处&可以没有;
- 字符串:
-
strchr(str,ch);
-
strstr(str1,str2);
-
在第一个中首次出现的位置;
- 结构体内数据定义空间分配:
-
与定义顺序与类型同时相关;
-
按照成员变量中占用空间最大的来作为分配单位,
-
同样成员变量的存储空间也是不能跨分配单位的,
-
如果当前的空间不足,则会存储到下一个分配单位中。
- typedef vs #define
-
#define 是 C 指令,用于为各种数据类型定义别名,与 typedef 类似,但是它们有以下几点不同:
-
typedef 仅限于为类型定义符号名称,
-
#define 不仅可以为类型定义别名,也能为数值定义别名,比如您可以定义 1 为 ONE。
-
typedef 是由编译器执行解释的,#define 语句是由预编译器进行处理的。
- #pragma 使用标准化方法,向编译器发布特殊的命令到编译器中
- 预定义宏:
-
__DATE__ 当前日期,一个以 "MMM DD YYYY" 格式表示的字符常量。
-
__TIME__ 当前时间,一个以 "HH:MM:SS" 格式表示的字符常量。
-
__FILE__ 这会包含当前文件名,一个字符串常量。
-
__LINE__ 这会包含当前行号,一个十进制常量。
-
__STDC__ 当编译器以 ANSI 标准编译时,则定义为 1。
- errno :
- errno、perror() 和 strerror()
-
C 语言提供了 perror() 和 strerror() 函数来显示与 errno 相关的文本消息。
-
perror() 函数显示您传给它的字符串,后跟一个冒号、一个空格和当前 errno 值的文本表示形式。
-
perror:自己的: 系统错误;
-
strerror() 函数,返回一个指针,指针指向当前 errno 值的文本表示形式。
-
strerror:返回系统错误文本;
-
让我们来模拟一种错误情况,尝试打开一个不存在的文件。您可以使用多种方式来输出错误消息,
-
在这里我们使用函数来演示用法。另外有一点需要注意,您应该使用 stderr 文件流来输出所有的错误。
-
FILE * pf;
-
int errnum;
-
pf = fopen ("unexist.txt", "rb");
-
if (pf == NULL)
-
{
-
errnum = errno;
-
fprintf(stderr, "错误号: %d\n", errno);
-
perror("通过 perror 输出错误");
-
fprintf(stderr, "打开文件错误: %s\n", strerror( errnum ));
-
}
**********************************************************/
在这里插入代码片
#include <stdio.h>
#include <math.h>
#include <string.h>
void adds(void)
{
int i = 0;
i++;
printf("%d\n", i);
out:
printf(" goto text 2 \n");
}
void sushu(int n)
{
if (n == 1) {
return;
}
/*********************************************************
* 素数:大于1的自然数,除了1和自己本身能整除;
*
*
*/
//1.暴力求解
#if 0
for (size_t i = 2; i < n; i++){
size_t j;
for (j = 2; j < i; j++)
{
if (i % j == 0)
break;
}
if (j == i)
{
printf("%d \n", i);
}
}
#endif
//2 . 使用奇数优化
#if 1
if (n == 2){
printf("%d \n", 2);
return;
}
for (size_t i = 3; i < n; i += 2) {
size_t j;
for (j = 2; j < i; j++)
{
if (i % j == 0)
break;
}
if (j == i)
{
printf("%d \n", i);
}
}
#endif // 1
}
//求n 以内素数和
void Sum_sushu_n(int n)
{
int sum = 0;
for (size_t i = 2; i < n; i++) {
size_t j;
for (j = 2; j < i; j++)
{
if (i % j == 0)
break;
}
if (j == i)
{
printf("%d \n", i);
sum += i;
}
}
printf("sum : %d \n", sum);
}
void shuzu_test()
{
char pag[3][12] = { {"abc"}, {"def"}, {"ijm"}};
printf("%d \n", sizeof(pag));
printf("%d \n", strlen(pag));
printf("%d \n", strlen(pag[1]));
printf("%d \n", sizeof(pag[1]));
char* ptr = pag;
int i = 0;
while (ptr++) //空间连续,同一位数组
{
if (i < sizeof(pag)){
printf("%c", *ptr);
}
i++;
}
}
enum MyEnum //枚举的定义可以在任意地方
{
Enum1 = 4,
Enum2,
Enum
};
enum MyEnum _enum;
void ptr_test()
{
/// <summary>
///
/// </summary>
char * p1 = 0x100;
short * p2 = 0x100;
int * p3 = 0x100;
float * p4 = 0x100;
double * p5 = 0x100;
printf("%p\n", (p1+1));
printf("%p\n", (p2+1));
printf("%p\n", (p3+1));
printf("%p\n", (p4+1));
printf("%p\n", (p5+1));
/*
0x101
0x102
0x104
0x104
0x108
*/
}
void func_ptr_test(void (*p)())
{
p();
return;
}
typedef struct
{
unsigned char a;
unsigned int b;
unsigned char c;
} debug_size1_t;
typedef struct
{
unsigned char a;
unsigned char b;
unsigned int c;
} debug_size2_t;
void struct_test()
{
printf("debug_size1_t size=%lu,debug_size2_t size=%lu\r\n",
sizeof(debug_size1_t), sizeof(debug_size2_t));
}
union MyUnion
{
char age;
char high;
char data[4];
};
//求数的阶乘
long fac(int n)
{
if (n <=1);
return 1;
return n * fac(n-1);
}
double factorial(unsigned int i)
{
if (i <= 1)
{
return 1;
}
return i * factorial(i - 1);
}
void func1(int n, ...)
{
//va_list valist;
//double sum = 0.0;
//int i;
///* 为 num 个参数初始化 valist */
//va_start(valist, num);
///* 访问所有赋给 valist 的参数 */
//for (i = 0; i < num; i++)
//{
// sum += va_arg(valist, int);
//}
///* 清理为 valist 保留的内存 */
//va_end(valist);
}
int main()
{
printf("%ld \n", fac(10));
//union MyUnion man;
//man.age = 'a';
//man.high = 'b';
//for (size_t i = 0; i < 2; i++)
//{
// printf("%c \n", man.data[i]);
//}
//
/*stdin;
#define stdin (__acrt_iob_func(0))
#define stdout (__acrt_iob_func(1))
#define stderr (__acrt_iob_func(2))*/
/*unsigned char a;
char b;
printf("%d \n", sizeof(a));
printf("%d \n", sizeof(b));*/
/*struct_test();*/
/* void (*p)() = ptr_test;
p();*/
//func_ptr_test(ptr_test);
/*
_enum = Enum1;
printf("%d \n", _enum);
printf("%d \n", sizeof(_enum));
*/
//shuzu_test();
//sushu(100);
//printf("-------------------------\n");
/*Sum_sushu_n(1000);*/
/*******************************************************
*
* goto 语句总结:
* 1. 用于对程序跳转资源释放,不能直接结束;
* 2. 深度循环退出,使用 break、continue 不便;
* 3. 不可以跨函数使用(局部变量);
* 函数:
* 内置函数:使用static修饰的函数,只能在本文件中使用;
* 外部函数:使用extern修饰的函数,使用时在本文件中要声明不定义;
*
* 内联函数是指用inline关键字修饰的函数。在类内定义的函数被默认成内联函数。
* 内联函数从源代码层看,有函数的结构,而在编译后,却不具备函数的性质。
* 内联扩展是用来消除函数调用时的时间开销。它通常用于频繁执行的函数,对于小内存空间的函数非常受益。
*
* 使用内联函数的时候要注意:
*
* 递归函数不能定义为内联函数
* 内联函数一般适合于不存在while和switch等复杂的结构且只有1~5条语句的小函数上,否则编译系统将该函数视为普通函数。
* 内联函数只能先定义后使用,否则编译系统也会把它认为是普通函数。
* 对内联函数不能进行异常的接口声明。
*
* 变量:定义位置(函数内<局部>,函数外<全局> , 函数内外之间< 形参 >)
* 1. 全局变量:全局存储区,静态区,静态存储单元;
* 2. 局部变量:保存在栈区,函数被调用时才动态分配;
* 3. 初始化:局部变量定义时不会被编译器自动初始化,全局变量会*
*
* *************************
* * int 0 *
* * char '\0' *
* * float 0 *
* * double 0 *
* * pointer NULL *
* *************************
* 数组:
* 1.多维数组在空间上还是一维分布;
* 2.数组作为形参传递给函数【char】
* a. char * arr;
* b. char arr[10];
* c. char arr[];
* 一般可以把长度传入,同时可以用长度防止访问越界;
* 枚举:4个字节,常用于switch语句;
*
* 指针:
* 作为函数返回值时,防止返回栈变量的地址;
* 运算:++ -- + - < >
* ptr+1 运算后的结果与指针指向类型相关,单位为指向数据类型的单位;
*
*
* char * p1 = 0x100;
* *********************************************
* * short * p2 = 0x100; *
* * int * p3 = 0x100; *
* * float * p4 = 0x100; *
* * double * p5 = 0x100; *
* * *
* * *
* * printf("%p\n", (p1+1)); 0x101 *
* * printf("%p\n", (p2+1)); 0x102 *
* * printf("%p\n", (p3+1)); 0x104 *
* * printf("%p\n", (p4+1)); 0x104 *
* * printf("%p\n", (p5+1)); 0x108 *
* *********************************************
* 函数指针:
* int (* p)(int ,int);
* int (* p)(int ,int) = &max; //此处&可以没有;
*
* 字符串:
* strchr(str,ch);
* strstr(str1,str2);
* 在第一个中首次出现的位置;
*
* 结构体内数据定义空间分配:
* 与定义顺序与类型同时相关;
* 按照成员变量中占用空间最大的来作为分配单位,
* 同样成员变量的存储空间也是不能跨分配单位的,
* 如果当前的空间不足,则会存储到下一个分配单位中。
*
* typedef vs #define
* #define 是 C 指令,用于为各种数据类型定义别名,与 typedef 类似,但是它们有以下几点不同:
* typedef 仅限于为类型定义符号名称,
* #define 不仅可以为类型定义别名,也能为数值定义别名,比如您可以定义 1 为 ONE。
* typedef 是由编译器执行解释的,#define 语句是由预编译器进行处理的。
*
* #pragma 使用标准化方法,向编译器发布特殊的命令到编译器中
*
*
* 预定义宏:
* __DATE__ 当前日期,一个以 "MMM DD YYYY" 格式表示的字符常量。
* __TIME__ 当前时间,一个以 "HH:MM:SS" 格式表示的字符常量。
* __FILE__ 这会包含当前文件名,一个字符串常量。
* __LINE__ 这会包含当前行号,一个十进制常量。
* __STDC__ 当编译器以 ANSI 标准编译时,则定义为 1。
*
* errno :
*
* errno、perror() 和 strerror()
* C 语言提供了 perror() 和 strerror() 函数来显示与 errno 相关的文本消息。
*
* perror() 函数显示您传给它的字符串,后跟一个冒号、一个空格和当前 errno 值的文本表示形式。
* perror:自己的: 系统错误;
*
* strerror() 函数,返回一个指针,指针指向当前 errno 值的文本表示形式。
* strerror:返回系统错误文本;
*
* 让我们来模拟一种错误情况,尝试打开一个不存在的文件。您可以使用多种方式来输出错误消息,
* 在这里我们使用函数来演示用法。另外有一点需要注意,您应该使用 stderr 文件流来输出所有的错误。
* FILE * pf;
* int errnum;
* pf = fopen ("unexist.txt", "rb");
* if (pf == NULL)
* {
* errnum = errno;
* fprintf(stderr, "错误号: %d\n", errno);
* perror("通过 perror 输出错误");
* fprintf(stderr, "打开文件错误: %s\n", strerror( errnum ));
* }
*
*
*
**********************************************************/
//for (size_t i = 0; i < 10; i++)
//{
// adds();
//}
//a = 3;
//printf("--------------------- %d\n", a);
/*
int i;
float f;
double d;
printf("%d \n", i);
printf("%f \n", f);
printf("%lf \n", d);*/
//printf("%d \a", 022);//18 16+2
return 0;
}