前言
我是一个初中生,过完暑假就是一个高一的学生了。在这个暑假里,我学习了韦东山老师和唐佐林老师的课程,所以我写下这个笔记来记录自己的成长历程。
C语言基础入门学习笔记
格式
#include <stdio.h>//<工具包>
#include <stdio.h>
int main()
{
int a;//正文
return 0;
}
格式示例
printf("%s\n","hello");
printf("%d\n",1+1);
printf("%s=%d","1+1",1+1);
printf("hello\n");
printf("%c\n",'4');
int a;//整数变量,范围大
short b;//整数变量,范围小
float c;//浮点数变量,范围小
double d;//浮点数变量,范围大
char e;//字符变量,单个字符
“%s"字符串,“\n”换行,”%d"整数,“%f"浮点数,”%c"字符
运算
四则运算
int a,b,c;
float d,e;
c=a%b;//c是a除以b的余数,"%"只能用于整数相除取余
c=d/e;//c是d除以e的整数部分,舍弃小数部分
c=a/b;//c是a除以b的商,不取余数
关系运算
int a,b,c;
a=1;
b=3;
c=a-b>=a+b;//关系不成立,结果为假,c=0
c=a-b<=a+b;//关系成立,结果为真,c=1
//由此可得以下变式
c=a!=b+b>a;//结果为0,注意优先级,可通过加括号改变运算顺序
逻辑运算
"&&“表示“并且”,“||”表示“或者”,”!“表示"反换”
下列为变式
int a=1;
int b=2;
int c=0;
c=a&&b;//c为1
c=!(a-b)||(a<b);//c为1
c=!!b;//c为1
C语言中,真值对应非零值,假值对应零值
位运算
以下为整数情况下的结论
16>>4=1=16/2^4
由此可得a>>b=a/2(进制)^b
16<<1=32=16*2^1
由此可得a<<b=a*2(进制)^b
常用进制转换:
十进制转换为二进制
二进制转换为十进制
小数点前或者整数要从右到左用二进制的每个数去乘以2的相应次方并递增,小数点后则是从左往右乘以二的相应负次方并递减。
1101.01(2)=120+021+122+123 +02-1+12-2=1+0+4+8+0+0.25=13.25(10)
所以总结起来通用公式为:
abcd.efg(2)=d20+c*21+b22+a*23+e2-1+f*2-2+g2^-3(10)
优先级总结
选择if
//示例
if(c>0)
{
printf("1");
}
else
{
if(c==0)
{
printf("2");
}
else
{
printf("3");
}
}
//示例(一元二次方程解的情况)
int a,b,c,d;
printf("请输入三个数\n");
printf("a(x^2)+b(x)+c=0\n");
scanf("%d",&a);
printf("\na=%d\n",a);
scanf("%d",&b);
printf("\nb=%d\n",b);
scanf("%d",&c);
printf("\nc=%d\n",c);
d=b*b-4*a*c;
if(a==0)
printf("该方程只有一个实数根");
else
{
if(d>0)
printf("该方程有两个不相等的实数根");
else if(d==0)
printf("该方程有两个相等的实数根");
else if(d<0)
printf("该方程没有实数根");
}
选择switch
循环
break和continue
signed和unsigned
unsigned a=2147483648;
printf("a=%u",a);
数据类型之间的本质差异是占用的内存
char占1字节 (-128~127) , short占2字节 (-32768~32767) , int占4字节 (-2147483648~2147483647)
float占4字节 , double占8字节
sizeof
示例
#include <stdio.h>
int main()
{
int c = sizeof(char);
int s = sizeof(short);
int i = sizeof(s);
int uc = sizeof(unsigned char);
int us = sizeof(unsigned short);
int ui = sizeof(unsigned int);
printf("c = %d\n", c);//1
printf("s = %d\n", s);//2
printf("i = %d\n", i);//4
printf("sizeof(float) = %d\n", sizeof(float));//4
printf("sizeof(double) = %d\n", sizeof(double));//8
printf("uc = %d\n", uc);//1
printf("us = %d\n", us);//2
printf("ui = %d\n", ui);//4
return 0;
}
long
long a=1;
printf("%ld",a);
printf("%d",sizeof(long));
long long b=2147483647;
printf("%lld",b);
printf("%d",sizeof(long long));
long c=1l;//"l"表示"l"之前的变量类型为long
long long d=2147483648u;//"u"表示unsigned,即无符号
经典知识补充
示例
int a=1;
int b=2;
a=b=a+b;//correct
a=a+7=b+1;//error
a=(int)(12.3/4);//correct
辅助语句
注释
示例
int a=1;//注释一
/*a=a+1;
printf("%d",a);*/注释二
赋值
示例
a+=1;//即a=a+1
a-=2;//即a=a-2
a*=3;//即a=a*3
a/=4;//即a=a/4
运算符
自增自减不支持浮点类型
逗号
goto
int a=1;
goto hhh;
a=100;
hhh:printf("%d",a);
goto极具在程序中破坏性,会破坏程序结构,造成程序难以理解和维护。现代软件开发已禁用goto。
常量
示例
#define N 5.5;//定义常量N的含义为5.5
示例
#include <stdio.h>
#define hi 1111
#define hello 22.22
enum
{
light = 3,
dark = 444,
};
int main()
{
printf("%f\n",hello);
printf("%d\n",dark);
return 0;
}
示例
#include <stdio.h>
#define hi 1111u
#define hello 22.22
#define hhh 0.114f
enum
{
light = 3,
dark = 444,
};
int main()
{
printf("%f\n",hello);
printf("%d\n",dark);
printf("%u\n",hi);
printf("%f\n",hhh);
return 0;
}
const(只读变量)
const int a=1;//定义一个只读变量a为1
int b=a;
printf("%d",b);//b为1
数组
多维数组
int a[10][10];
a[6][3]=8;
示例
#include <stdio.h>
int main()
{
int a[3][3];
int i = 0;
int j = 0;
for(i=0; i<3; i++)
{
for(j=0; j<3; j++)
{
printf("Input a[%d][%d]: ", i, j);
scanf("%d", &a[i][j]);
}
}
printf("Matrix:\n");
for(i=0; i<3; i++)
{
for(j=0; j<3; j++)
{
printf("%d ", a[i][j]);
}
printf("\n");
}
for(i=0; i<3; i++)
{
for(j=0; j<3; j++)
{
if( i < j )
{
int t = a[i][j];
a[i][j] = a[j][i];
a[j][i] = t;
}
}
}
printf("Matrix-T:\n");
for(i=0; i<3; i++)
{
for(j=0; j<3; j++)
{
printf("%d ", a[i][j]);
}
printf("\n");
}
return 0;
}
字符数组与字符串
示例
#include <stdio.h>
#include <string.h>
int main()
{
int c=strlen("hahaha");
printf("\n%d\n",c);//输出6
char s1[]="happy";
char s2[]="apple";
if(strcmp(s1,s2)==0)
{
strcpy(s1,s2);
printf("\n%s\n",s1);//输出apple
}
else
{
strcat(s1,s2);
printf("\n%s\n",s1);//输出happyapple
}
return 0;
}
程序中的函数
#include <stdio.h>
int hahaha (int x)
{
int y=2x-2;
return y;
}
int main()
{
int a;
a=hahaha(5);//a=5*2-2=8
return 0;
}
函数调用
函数定义
void
void a()
{
//表示接受任何参数
}
void b(void)
{
//表示不接受任何参数
}
return
函数参数
数组参数
变量
变量的作用域
变量的生命区
作用域和生命期
静态变量
#include <stdio.h>
int global;
int func(int x)
{
static int s_var; // 全局数据区中的变量,默认初始化为 0
// 并且,只做一次初始化
s_var += x;
return s_var;
}
int main()
{
int i = 0;
for(i=1; i<=5; i++)
{
printf("func(%d) = %d\n", i, func(i));
}
printf("func(0) = %d\n", func(0));
printf("global = %d\n", global);
return 0;
}
总结
递归函数
宏
指针
#include <stdio.h>
int main()
{
int var=0;
int*pVar=NULL;
int another=0;
printf("%d\n",var);
printf("%p\n",pVar);
pVar=&var;//使用指针保存变量地址
*pVar=100;
printf("%d\n",var);//*pVar等价于var,var=100
printf("%p\n",pVar);
pVar=&another;//改变pVar的指向,使得pVar保存another地址
*pVar=1000;//another=1000
printf("%d\n",another);
printf("%p\n",pVar);
return 0;
}
深入理解指针与地址
#include <stdio.h>
int main()
{
int i = 10;
float f = 10;
int* pi = &f; // WARNING
float* pf = &f; // OK
printf("pi = %p, pf = %p\n", pi, pf);
printf("*pi = %d, *pf = %f\n", *pi, *pf);
pi = i; // WARNING
*pi = 110; // OOPS
printf("pi = %p, *pi = %d\n", pi, *pi);
return 0;
}
使用指针在函数中交换两个变量的值
#include <stdio.h>
void func(int* p)
{
*p = 100; // 修改内存中 4 字节的数据,即:修改一个整型变量的值
}
void swap(int* pa, int* pb)
{
int t = 0;
t = *pa;
*pa = *pb;
*pb = t;
}
int main()
{
int var = 0;
int a = 1, b = 2;
printf("1. var = %d\n", var);
func( &var );
printf("2. var = %d\n", var);
printf("3. a = %d, b = %d\n", a, b);
swap(&a, &b);
printf("4. a = %d, b = %d\n", a, b);
return 0;
}
使用指针进行连加和连乘
#include <stdio.h>
int calculate(int n, long long* pa, long long* pm)
{
int ret = 1;
if( (1 <= n) && (n <= 20) )
{
int i = 0;
*pa = 0;
*pm = 1;
for(i=1; i<=n; i++)
{
*pa = *pa + i;
*pm = *pm * i;
}
}
else
{
ret = 0;
}
return ret;
}
int main()
{
long long ar = 0;
long long mr = 0;
if( calculate(5, &ar, &mr) )
printf("ar = %lld, mr = %lld\n", ar, mr);
return 0;
}
总结
指针与数组
#include <stdio.h>
int main()
{
int a[] = {1, 2, 3, 4, 0};
int* p = a; // a 的类型为 int*, &a[0] ==> int*
int (*pa) [5] = &a;
printf("%p, %p\n", p, a);
p++;
*p = 100; // a[1] = 100;
printf("%d, %d\n", *p, a[1]);
printf("%p, %p\n", &a, a);
p = pa; // WARNING !!!!
p = a;
while( *p )
{
printf("%d\n", *p);
p++;
}
return 0;
}
#include <stdio.h>
int main()
{
int a[] = {1, 2, 3, 4, 5};
int* p = a;
int i = 0;
// a[i] <==> *(a+i) <==> *(p+i) <==> p[i]
for(i=0; i<5; i++)
{
printf("%d, %d\n", a[i], *(a + i));
}
for(i=0; i<5; i++)
{
printf("%d, %d\n", a[i], p[i]);
}
for(i=0; i<5; i++)
{
printf("%d, %d\n", p[i], *(p + i));
}
printf("a = %p, p = %p\n", a, p);
printf("&a = %p, &p = %p\n", &a, &p);
return 0;
}
#include <stdio.h>
int main()
{
int a[] = {1, 2, 3};
int* p = a;
int v = *p++;
char* s = NULL;
printf("%p\n", "D.T.Software");
printf("%p\n", "D.T.Software");
printf("v = %d, *p = %d\n", v, *p);
printf("First = %c\n", *"D.T.Software");
s = "D.T.Software";
while( *s ) printf("%c", *s++);
printf("\n");
return 0;
}
指针与函数
#include <stdio.h>
int add(int a, int b)
{
return a + b;
}
int mul(int a, int b)
{
return a * b;
}
int calculate(int a[], int len, int(*cal)(int, int))
{
int ret = a[0];
int i = 0;
for(i=1; i<len; i++)
{
ret = cal(ret, a[i]);
}
return ret;
}
int main()
{
int a[] = {1, 2, 3, 4, 5};
int (*pFunc) (int, int) = NULL;
pFunc = add;
printf("%d\n", pFunc(1, 2));
printf("%d\n", (*pFunc)(3, 4));
pFunc = &mul;
printf("%d\n", pFunc(5, 6));
printf("%d\n", (*pFunc)(7, 8));
printf("1 + ... + 5 = %d\n", calculate(a, 5, add));
printf("1 * ... * 5 = %d\n", calculate(a, 5, mul));
return 0;
}
指针与堆空间
#include <stdio.h>
int main()
{
char c = 0;
int i = 0;
float f = 2.0f;
double d = 3.0;
void* p = NULL;
double* pd = NULL;
int* pi = NULL;
/* void* 指针可以保存任意类型的地址 */
p = &c;
p = &i;
p = &f;
p = &d;
printf("%p\n", p);
// void* 类型的指针无法访问内存中的数据
// printf("%f\n", *p);
/* void* 类型的变量可以直接合法的赋值给其他具体数据类型的指针变量 */
pd = p;
pi = p;
// void* 是例外,其他指针类型的变量不能相互赋值
// pd = pi;
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int main()
{
int* p = malloc(4); // 从堆空间申请 4 个字节当作 int 类型的变量使用
if( p != NULL ) // 如果申请失败 p 为 0 ,即:空值
{
*p = 100;
printf("%d\n", *p);
free(p);
}
p = malloc(4 * sizeof(int));
if( p != NULL )
{
int i = 0;
for(i=0; i<4; i++)
{
p[i] = i * 10;
}
for(i=0; i<4; i++)
{
printf("%d\n", p[i]);
}
free(p);
}
return 0;
}
自定义数据类型
typedef
#include <stdio.h>
#include <string.h>
typedef unsigned char byte;
void func()
{
typedef byte uint8;
uint8 var = 200;
byte b = var; // 本质为相同类型变量之间的初始化
printf("sizeof(uint8) = %d\n", sizeof(uint8));
printf("var = %d\n", var);
printf("b = %d\n", b);
}
int main()
{
// uint8 var = 1; // ERROR
byte b = 128;
func();
printf("sizeof(byte) = %d\n", sizeof(byte));
printf("b = %d\n", b);
return 0;
}
struct
#include <stdio.h>
#include <string.h>
typedef struct Student Stu;
struct Student
{
char name[20];
int id;
short major;
};
int main()
{
Stu s;
Stu* ps = &s;
strcpy(ps->name, "Delphi");
ps->id = 1;
ps->major = 908;
(*ps).major = 910; // ==> s.major = 910
printf("s.name = %s\n", s.name);
printf("s.id = %d\n", s.id);
printf("s.major = %d\n", s.major);
return 0;
}
union
#include <stdio.h>
#include <string.h>
int a()
{
union
{
int i;
char a[4];
} test={0};
test.i=1;
return (test.a[0]==1);
}
int main()
{
printf("%d\n",a());//"1"为小端系统,"2"为大端系统
return 0;
}
enum
#include <stdio.h>
#include <string.h>
enum Day { MON = 1, TUE, WED, THU, FRI, SAT, SUN };
enum Season { Spring, Summer = 3, Autumn, Winter = -1 };
enum { CONSTANT = 12345 };
int main()
{
enum Day d = TUE;
enum Season s = Winter;
int i = SUN;
int j = Autumn;
printf("d = %d\n", d); // 2
printf("s = %d\n", s); // -1
printf("i = %d\n", i); // 7
printf("j = %d\n", j); // 4
d = 0;
s = -2;
printf("d = %d\n", d);
printf("s = %d\n", s);
printf("sizeof(enum Day) = %d\n", sizeof(enum Day));
printf("sizeof(enum Season) = %d\n", sizeof(enum Season));
printf("CONSTANT = %d\n", CONSTANT);
// CONSTANT = 54321;
return 0;
}