预处理+字符串
预处理
一、什么是预处理
预处理指的的就是代码在执行指向所做的事情,以#开头
二、常见的预处理
include<xxx.h>
使用<>,编译器会到系统的路径下找头文件,找不到就会报错
使用"xxx.h",系统会首先到当前目录,也就是你的程序所在的目录,没有就去系统的路径下去找,找不到会报错
注意:包含系统的头文件就用<>,包含自己写的头文件就用"".
三、#define==》宏替换,是一个预处理命令
1.#define是C语言的宏定义,本质是替换,会在预处理阶段对程序中所有出现"宏名"的地方进行替换
一般替换代码比较少的
2.定义:
define 宏名 内容==》看你自己加不加分号
define 宏名
#define PI 3.1415926
#define add 1+4
int main()
{
double a=PI;
//等价于
//double a=3.1415926;
int a=2*add;
//答案是2*1+4=6;
//只是替换,不会进行其他操作
}
3.实例
#include <stdio.h>
#include<stdlib.h>
#include<time.h>
#define SIZE 10
//#undef SIZE
//取消宏定义
//可以运用到推箱子这样的程序,循环比较多的,方便改动
int main()
{
srand((unsigned int)time(NULL));//随机数种子
//printf("%d", rand()%10);
int arr[SIZE] = { 0 };
for (int i = 0; i < SIZE; i++)
{
arr[i] = rand() % 10+1;//随机生成1-10范围的随机数
printf("%d ", arr[i]);
}
getchar();
getchar();
return 0;
}
4.带参数的宏定义
带参宏:以空间换时间,没有入栈出栈
#define add(a,b) a+b
//形参没有类型,没有返回值,本质是替换
//什么类型都行,但要考虑两者能不能相加
//比如结构体就不能相加
int add(int a,int b)
{
return a+b;
}
//以时间换空间
//形参有类型,有返回值,本质是替换,函数有入栈出栈
/*
虽然这个函数和上面的宏定义效果一样,但这个函数只能相加int类型的数,而宏定义没有规定类型,可以是整型,浮点型,...之类的相加
*/
int main()
{
int a=add(1,2);
printf("%d\n",a);//输出3
}
四、头文件,预编译条件
#pragma once :
只包含一次,用来防止重复包含
就是说你写了两个一样的#include<stdio.h>,但是只会展开一次这个头文件
C语言中:
#ifdef 宏名
//
// 代码段
//
#endif
#ifdef 宏名
//
// 代码段1
//
#else
//
// 代码段2
//#endif
//如果宏名定义了执行代码段1,没有定义执行代码段2
/*
#pragma once
//只适用于windows
#ifndef ==》如果没有定义这个宏名,那么就执行下面的代码
#define==》那么就会定义它
可以跨平台
代码块
#endif
==>活动预处理器块
就是说开始你是没有定义宏名的,当你写了#include<stdio.h>时,那个宏名就被定义了,如果你写了两个#inlcude<stdio.h>,但是第一次已经定义了,所以从#ifndef开始就不会执行下面的代码了
*/
五、几个常用的预处理命令
#include<stdio.h>
int main()
{
printf("%d\n", __LINE__);//输出当前行号
printf("%s\n", __FILE__);//输出编译文件名字
printf("%s\n", __DATE__);//输出当前编译日期
printf("%s\n", __TIME__);//输出当前编译时间
}
六、字符串
char nn[5]={"abcd"};
//这样才是对的,有五个字节空间,但是要留一个字节给,'\0',结尾
//如果用
scanf("%s",nn);
//如果输入as x
//那么只会输出as,因为只会输出空格之前的内容
//字符串数组要用strcpy来拷贝,将一个字符串里的内容赋给另一个字符串
char a1[10]={"avade"};
char a2[10]={"kjds"};
strcpy(a1,a2);
if(strcmp(a1,a2)==0)
{
printf("两个字符串相等");
}
else
{
printf("两个字符串不相等");
}
char s[10] = { 0 };
for (int i = 0; i < 9; i++)
{
sprintf(&s[i], "%d", i);
}
puts(s);
//输出012345678
int arr[10];
memset(arr, 0, sizeof(arr));
for (int i = 0; i < 10; i++)
{
printf("%d", arr[i]);
}
//memset按位赋值,作用初始化一块地址
char s1[10] = "snwjdb";
char s2[10] = { 0 };
memcpy(s2, s1 + 3, 3);
//效果是将s1中的jdb拷贝到s1中,将后面的考给前面
int a = 10;
int b = 20;
memcpy(&a, &b, 4);//int是四个字节
printf("a=%d\tb=%d\n", a, b);
//输出是a=20,b=20;
strcmp(s1,s2)
比较第一个字符的大小,比的ASCII码表中对应的十进制数
返回值为0,两个字符串相等
返回值<0,s1<s2
返回值>0, s1>s2
//gets将回车视为输入结束的标志,空格不是,所以可以实现输入带空格的字符串
gets只能用于字符串的输入