【前言】C语言的学习也有几天时间了,从刚开始的完全没有接触到对C语言有了一小点认识,中间也经历了好奇到惊叹,原来计算机语言也像数学一样在生活中处处可见。
一,先了解C语言的基础知识,对C语言有一个大概的认知
1,什么是C语言?
C语言是一门计算机编程语言,用C语言编译器可以让计算机执行我们的命令。在计算机的中央处理器(CPU)中,只能读懂用二进制编码(0、1数列),为了普及C语言,现在创造出了许多的计算机编程语言,C语言就是其中之一。
2,第一个C语言程序
main函数是程序的入口,一个工程中有且仅有一个main函数。
{}中间的是函数体
printf函数包含在stdio.h头文件中,头文件对你使用的函数进行定义,不定义编译器会警告
; 相当于中文里的句号,表示一条语句的结束
3,数据类型
整型(int short long long long char),前面加上unsigned可以扩大范围
浮点型(float double)
可以使用sizeof()求所占大小
如:
printf("%d",sizeof(int));
应用:char ch = 'A';
int num = 10;
float weight = 62.5;
这么多数据类型是为了更方便表达生活中不同的值。
4,变量和常量
变量:生活中有些值是会发生改变的(身高、体重、成绩)
变量分为局部变量和全局变量
常量:生活中不会改变的值(血型、身份证号)
4.1局部变量和全局变量的使用
局部变量在函数内部使用,作用于函数体
全局变量在函数体外部使用,作用于整个工程
global是全局变量,local是局部变量
注意:当局部变量和全局变量同名的时候,局部变量优先使用!
4.2变量的作用域和生命周期
1. 局部变量的作用域是变量所在的局部范围。
2. 全局变量的作用域是整个工程。
4.3常量
C语言中常量和变量的定义形式有所差异
~字面常量
~const修饰的常变量
~#define定义的标识符常量
~枚举常量
5.字符串/转义字符/注释
5.1字符串
“Hello World!”
这种由双引号引起来的一串字符叫做字符串,字符串是以‘\0'结束的,但是计算字符串长度时,’\0'不计入在内(sizeof包含在内,strlen不包含在内)
#include <stdio.h>
//下面代码,打印结果是什么?为什么?(突出'\0'的重要性)
int main()
{
char arr1[] = "bit";
char arr2[] = {'b', 'i', 't'};
char arr3[] = {'b', 'i', 't', '\0'};
printf("%s\n", arr1);
printf("%s\n", arr2);
printf("%s\n", arr3);
return 0;
}
打印arr2时计算机找不到结束标志,出现乱码。
5.2转义字符
这里的\t是一个转义字符(水平制表符)
如果想要打印一个字符,字符里是双单引号,应该怎样做?
printf("%c",'\'');
打印一个字符串里是双引号呢?
printf("%s","\"");
计算字符串长度:
#include <stdio.h>
int main()
{
printf("%d\n", strlen("abcdef"));
// \62被解析成一个转义字符
printf("%d\n", strlen("c:\test\628\test.c"));
return 0;
}
所以\62是一个字符长度
5.3注释
单行注释://xxxxxxxxx
多行注释:/* xxxxxxxxx
xxxxxxxx */
方便别人和自己理解代码
6.语句
6.1选择语句
如果你好好学习,将会拿到好offer
否则,只能去烤红薯。
#Include<stdio.h>
int main()
{
int a = 0;
scanf("%d",&a);
if(a==1)
printf("好offer\n");
else
printf("卖红薯\n");
return 0;
}
有多个选择时,用else if
6.2循环语句
~while语句
~for语句
~do...while语句
先学习while语句,后面再具体讨论其他语句
#include<stdio.h>
int main()
{
int line = 0;
printf("好好学习\n");
while(line<=2000)
{
line++;
printf("好好敲代码\n");
}
if(line>2000)
printf("好offer\n");
return 0;
}
line++ (line = line + 1)
7,函数
#include<stdio.h>;
/*
int main()
{
int num1 = 0;
int num2 = 0;
int sum = 0;
printf("请输入两个操作数:");
scanf("%d %d", &num1, &num2);
sum = num1 + num2;
printf("sum=%d\n", sum);
return 0;
}
*/
int add(int x, int y)
{
int z = x + y;
return z;
}
int main()
{
int num1 = 0;
int num2 = 0;
int sum = 0;
printf("请输入两个操作数:");
scanf("%d %d", &num1, &num2);
sum = add(num1, num2); //引用add函数
printf("sum=%d\n", sum);
return 0;
}
一个工程中需要用到多次同一个函数时,定义这个函数可以提高效率
8,数组
一种相同类型元素的集合
int arr[10] = {0};
有10个int类型的元素
8.1数组的下标
C语言规定:数组的每一个元素都有下标,下标是从0开始的
数组可以通过下标来访问
一共有(元素个数减1)个下标,就是最后一个元素下标为(元素个数减1)
8.2数组的使用
#include<stdio.h>
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
printf("%d\n", arr[0]);
return 0;
}
注意:数组本身就是地址,所以用scanf函数赋值的时候,不用取地址。
9,操作符
算术操作符:+ - * / %
移位操作符:>> <<
位操作符:& ^ |
赋值操作符:= += -= *= /= &= ^= |= >>= <<=
a = a+5(a +=5)
单目操作符:
if (a)
{
//如果a为真,做事
}
if (!a)
{
//如果a为假,做事
}
sizeof是一个操作符
按位取反作用的是补码,正整数原码、反码、补码相同
若要求一个整数的按位取反值,先求出整数的补码,再按位取反求出改变之后的补码,推出原码
#include<stdio.h>
int main()
{
int a = 10;
int b = 0;
b = a++; //先使用再++
printf("b=%d\n", b); //b=10
printf("a=%d\n", a); //a=11
/*b = ++a; //先++再使用
printf("b=%d\n", b); //b=11
printf("a=%d\n", a);*/ //a=11
return 0;
}
关系操作符:
逻辑操作符:(并且/或者)
条件操作符:exp1 ? exp2 : exp3
#include<stdio.h>
int main()
{
int a = 1;
int b = 3;
int c = 0;
/*if (a > b)
c = a;
else
c = b;*/
c = a > b ? a : b; //如果a>b成立,则c=a,否则c=b; exp1?exp2:exp3;
printf("%d\n", c);
return 0;
}
逗号表达式:exp1, exp2, exp3, …expN
#include<stdio.h>
int main()
{
int a = 1;
int b = 3;
int c = 0;
//a=3 b=4 c=7
int d = (a = a + 2, b = b + 1, c = b + a);//d=c=7
//逗号表达式,从左向右依次计算,整个表达式的结果是最后一个表达式的结果
printf("%d%d%d%d\n",a,b,c, d);
return 0;
}
下标引用、函数调用和结构成员:[] () . ->
[]下标引用,数组可以通过下标来访问
调用函数的时候,函数后面的()就是函数调用操作符
10,关键字
常见关键字:
注意: 关键字是C语言提供的,不能自己创建关键字
关键字不能是变量名
空间越小,数度越快,造价也越高
10.1关键字typedef
10.2关键字static
~修饰局部变量
#include<stdio.h>
void test()
{
int i = 0;
i++;
printf("%d\n", i);
}
int main()
{
int i = 0;
for (i = 0; i < 10; i++)
{
test(); //i每次进入test函数时初始为0
}
return 0;
}
#include<stdio.h>
void test()
{
static int i = 0; //static在翻译时赋予初值,每次调用函数不再重新赋予初值,函数结果不销毁
i++;
printf("%d\n", i);
}
int main()
{
int i = 0;
for (i = 0; i < 10; i++)
{
test();
}
return 0;
}
static修饰局部变量改变了变量的生命周期, 让静态局部变量出了作用域依然存在,到程序结束,生命周期才结束。
~修饰全局变量
#include<stdio.h>
static int g_val = 2018;
int main()
{
printf("%d\n", g_val);
return 0;
}
static修饰的全局变量只能在本源文件内使用,虽然全局变量具有外部链接属性,但是被static修饰之后,就变成了内部链接属性,所以不能在其他源文件中使用
~修饰函数
#include<stdio.h>
static int Add(int x, int y)
{
return c+y;
}
int main()
{
printf("%d\n", Add(2, 3));
return 0;
}
static修饰的函数也只能在本源文件内使用
11,define定义常量和宏
define是一个预处理指令
11.1define定义符号
定义一个变量,也可以在函数内部定义
11.2定义宏
12,指针
12.1内存
内存是电脑上特别重要的存储器,计算机中程序的运行都是在内存中进行的 。
为了方便存储,把内存分成了一个个内存单元,每个内存单元的大小是1字节
为了能够访问到每一个内存单元,将内存单元进行了编号,代表内存单元的地址
变量存在于创建内存中的,因为每个内存单元都有地址,所以变量是有地址的
打印地址:
#include<stdio.h>
int main()
{
int num = 10; //num变量大小是4字节
# //取地址,取出的是第一个字节的地址(较小的地址)
printf("%p\n",&num); //打印地址的转义字符是%p
return 0;
}
指针的使用
#include<stdio.h>
int main()
{
int num = 10;
int* p = # //p为指针变量,用来存放地址的。*是用来说明p是指针变量的
*p = 20; //*解引用操作,*p就是通过p里的地址找到num。int说明p的对象是int类型的
char ch = 'A'; //pa的对象是char类型的
int* pa = &ch;
return 0;
}
指针变量p里存放的是num变量的第一个地址(最小的地址),*p从p中找到num的地址
12.2求指针变量的大小
#include <stdio.h>
//指针变量的大小取决于地址的大小
//32位平台下地址是32个bit位(即4个字节)
//64位平台下地址是64个bit位(即8个字节)
int main()
{
printf("%d\n", sizeof(char *));
printf("%d\n", sizeof(short *));
printf("%d\n", sizeof(int *));
printf("%d\n", sizeof(double *));
return 0;
}
指针大小在32位平台是4字节,在64位平台是8字节。
内存(调试——窗口——内存) 可以看到变量的地址
监视(调试——窗口——监视) 调试的时候可以看到变量的大小变化,方便查看代码怎么运行的,也更好查找bug
13,结构体
结构体使C语言有能力描述更复杂的类型
比如描述学生,学生包含: 名字+年龄+性别+学号 这几项信息。
struct Stu
{
char name[20];//名字
int age; //年龄
char sex[5]; //性别
char id[15]; //学号
};
结构体的初始化:
//打印结构体信息
struct Stu s = {"张三", 20, "男", "20180101"};
//.为结构成员访问操作符
printf("name = %s age = %d sex = %s id = %s\n", s.name, s.age, s.sex, s.id);
//->操作符
struct Stu *ps = &s;
printf("name = %s age = %d sex = %s id = %s\n", ps->name, ps->age, ps->sex, ps-
>id);
. 和 ->是结构成员
刚开始对C语言的大致了解就是这些,这些都是很浅显的涉及一点点。对待一件事情,我们要从整体出发,一步步搞懂它的每一部分,这样我们可以形成一个基本的框架,学习每一部分的时候都能更清晰明了。
最后最后,语法很重要,我们学习的一些函数只不过是辅助我们实现我们想达到的目的,心中有目标,才能更好的调用我们应该使用的函数。