前言:
1.初学习了c语言,感觉还是很不错的,哈哈~~。下面让我来分享下我目前对c的认识
题外:后面有关于c语言风格培养的《高质量的c-c++编程》PDF版链接,有需要自拿。哈哈~~。
一.初识c语言
1.1计算机语言的发展过程:由需求促进发展,由不成熟逐渐成为流行。
早期的科学家通过数字1和0的组合控制硬件计算机的运行。后来在需求下,人们创建了助记符(汇编语言).但还是不能满足需求,于是B语言出现,再后来高级语言C,c++,java等相继出现。但不同地方语言规范不同,为消除这种交流障碍,促进语言的融洽,1989年,ANSI(美国国家标准协会)制定了一套c语言规定(c89),1990年,国际标准化组织(IOS)也制定了一套规定(c90).1999年,ANSI/IOS(C9X委员会)联合委员会共同制定了c99;2011年,C9x发布了(C11)标准。至此C语言成为世界流行语言。目前使用较多的是c89/c90(2个几乎等同),
|
1.2什么是c语言?
c语言是一种面向过程的计算机编程语言,广泛用于底层C语言的设计目标 是提供一种 能简易编译,处理低级存储器,产生少量机器码以及不需要任何运行环境支持便能运行的编程语言。
|
选择C语言的理由:流行性,高效性,可移植性高,强大而灵活,面向程序员。
1.流行性:c是一门流行语言。其融合了计算机科学理论和实践的控制特性。便于用户完成自顶向下的规划,结构化编程和模块化设计。使得c语言编写的程序更易懂,更可靠。
|
2.高效性:c是高效的语言。c语言具有通常汇编语言才有的微调控控能力,可以根据具体情况一获得最大运行速度,最有效的使用内存。
|
3.可移植性高:c是可移植的语言。我们知道不同操作系统其运行方式不同。而我们想在不同系统运行c程序,需要我们在少量更改程序的条件下,仍能运行c程序。这必然要求我们的语言可移植性高。而在这些语言中,c语言崭露头角,其可移植性非常高
|
4.强大而灵活:许多操作系统,如UNIX系统大部分也是通过c语言编写的。另外很多程序编译器,解释器也是用c语言编写的。
|
5.面向程序员:c语言的强大,可以清晰的让程序员简洁的表达自己的想法与意图。
|
简单的c程序
#include<stdio.h>
int main()
{printf("helloworld!");
return 0;
}
据说在业界能这句话能给你的编程之旅带来好运!你好世界!
|
三.c语言的语法规则
3.1 c中的数据类型:整形,浮点型,字符型及其所占空间大小
整型
|
名字
|
int
|
(普通整形),
|
short (int)可以省略(int)
|
短整形
|
long
|
长整形
|
long long
|
更长的整形
|
unsigned int
|
无符号(—)整形(只能为正)
|
signed int
|
有符号整型(一切整数)
|
浮点型:
|
名字
|
float
|
单精度浮点数型
|
double
|
双精度浮点型
|
3.1.2 每种数据类型的在内存中的大小
补充:
1.sizeof(类型)
|
1.它是运算操作符,不是函数
|
2.它用于测定数据在内存中的字节(byte)大小,字符串结束标志‘\0’也要被计算内存。
|
2.strlen(字符数组名)
|
1.它是函数,不是操作符。
|
2.它用于测定字符数组长度。在测定长度时以’\0’为字符串结束标志。
|
3.字节(byte)
计算机的单位:
内存单位
|
名字
|
补充
|
bit
|
比特
|
计算机最小内存单元
|
byte
|
字节
|
1byte=8bit
|
kb
|
|
1kb=1024byte
|
mb
|
|
1kb=1024kb
|
gb
|
|
1kb=1024mb
|
tb
|
|
1kb=1024gb
|
pb
|
|
1kb=1024tb
|
我们知道计算机能识别的机器语言(二进制语言)(一定顺序的1/0),而对于每个二进制1/0在内存中都要占有一定的空间,我们规定每个这样的1/0所占的空间为1bit(计算机中的最小内存空间)。而计算机中的数据是按字节,分配空间的,即认为1byte为运行时的内存单元。
|
01000100 占用1个字节空间(8个bite位)
|
而对于数据类型我们规定:
类型
|
内存大小
|
整型(int)
|
4个字节(32bite位)
|
短整形(short)
|
2个字节(16个bite位)
|
long long型
|
8个字节。
|
类型
|
内存大小
|
字符型
|
一个字节(8个bite位)。
|
类型
|
内存大小
|
单精度型(float)
|
4个字节(32个bite位)
|
双精度型(double)
|
8个字节(64个bite位)。
|
==另外c语言规定:sizeof(long)>sizeof(int)=4;具体long型所占字节大小,依据不同编译器结果不同。
|
3.2变量,常量
3.2.1.变量:可以随时改变的量(数据).如:年龄,身高等;
3.2.2.常量:不能改变的量(数据)。如:圆周率,血型等。
3. 2.3定义变量的方式:
数据类型+自定义数据名称+初始化+语句结束标志“;”(分号)
初始化依据条件可以不进行初始化。
如 年龄是整形数据
身高是浮点型数据
字母是字符型数据
int age=19;
float length=170f;
char a='w';
3.2.4变量的使用:
#include<stdio.h>
int main()
{int age=19;
float length=170f;//c默认浮点型数据为double型,如果非要float,只需要在后面加f;
char name[]="***";//名字是由多个字符组合成的,因此在c中我们定义字符数组来表示字符串;
printf("年龄=%d\n",age);
printf("长度=%f\n",length);
printf("名字=%s",name);//以字符串的形式打印字符数组name中的每个元素;
return 0;
}
3.2.5变量的分类
局部变量:
定义在一对{}内的变量都是局部变量,无论是main函数还是普通函数。
|
全局变量:
注意
当全局变量与局部变量冲突时,遵从“局部变量优先原则”
|
3.2.6变量的作用域与生命周期————有效使用变量
局部变量:
1.作用域:在所创建位置的一对{}内的任何地方都可以使用:
|
2.生命周期:
|
局部变量自创建的一对{}始,到出这对{}为止,这段时间为其生命周期;**
|
right:
a创建于最外面的{},所以main函数内的任何地方都可以使用。
|
a创建于里面的{},所以里面{}内的任何地方都可以使用。
|
error
思考
#include<stdio.h>
int main()
{{int a=1;printf("%d\n", a);}printf("%d\n", a);return 0;
}
#include<stdio.h>
int main()
{int a = 1;{int a=1;printf("%d\n", a);}printf("%d\n", a);return 0;
}
全局变量:
|
1.作用域:自创建到程序结束的任何地方都可以使用。
|
2.生命周期:自创建到程序结束为其生命周期。
|
3.2.7常量:
1.字面常量:血型,名字等
2.const修饰常变量(一旦const就不可更改):
#include<stdio.h>
int main()
{
const int a=19;
a=22;//变量一旦const就不可更改,重新赋值。
printf("%d",a);
return 0;}
3.#define定义的标识符常量
注意
1.define定义的宏常量不占用内存,它只会傻瓜式的语言替换。
|
分析:
结果并不是20,而是12的原因是:t=x+2*2;
|
4.枚举常量
当一个变量的所有可能都可知的情况下,我们常定义枚举常量;如性别,数据类型等
|
c语言规定:枚举常量中的第一个常量在数值上是0,其它依次加1。如果人为的初始化第一个常量,其它常量任然依次加1.**
|
3.3字符与字符串+转义字符+注释;
3.3.1.字符与字符串:
字符:像‘w’这种由一对‘ ’所引用的字符。
字符串:”name“像这种用一对” “所引用的连续字符,称为字符串。
因为c语言中没有字符串型数据,因此我们用字符数组定义字符串;
3.3.2.转义字符:
补充:
1.在计算机中,为了方便字符型与实型数据间的运算,我们人为的规定每个字符对应的一个十进制数。为此我们制定了ASII表
|
注意
常用转义字符:‘\n’,’\t’,’\ddd’,’\xdd’;
|
注意
3.3.3.注释
1.在c程序中我们想解释自己的程序时,我们常使用“//”;
|
2.在c程序中我们想保留部分程序,不让其起作用时,
|
注意
3.4 c语言的3种结构:顺序,选择,循环。
3.4.1顺序:一步一步执行代码。
3.4.2选择结构(分支语句):
注意
3.4.2.1 if语句
1.if语句的2种形式
第一种
if(表达式){语句体}
else 语句体
第二种
if(表达式){语句体}
else if(表达式) {语句体}
…
else 语句体
注意
1.我们规定else与最近的if匹配.
|
2.注意if语句体中的关键字break,continue;
|
看题
#include <stdio.h>
int main()
{int a = 0;int b = 2;if(a == 1)if(b == 2)printf("hehe\n");elseprintf("haha\n");
return 0;
}
思考这题的输出结果
答案:
什么都不输出思考注意中的第一点
2 .switch语句:
1.switch语句的形式
switch(整形表达式)
{
case 整形常量表达式:语句;
…
}
注意
1.switch中的整形表达式不可以为浮点型数据,但可以为,枚举类型(可以当作是整形常量),字符型数据(计算机在碰到字符新数据时会将它自动转化为整形进行运算)(图一)
|
2.case 中的必须为整形常量,或者是枚举类型(枚举也看以看作是一种特殊常量)
|
3.switch中的关键字break是用于分开语句块的。且不能使用关键字continue;(图二)
|
4.当执行的case没有break作为跳出switch时,其会==,默认==继续执行下面的case,直到再次遇到break;(图三)
|
5.虽然switch中的default是默认选项的意思,但使用时多留意其前面是否有break;再次体现第三点的重要性(图四)
|
6.default 可以放在switch语句体内的任意位置
|
看图
图一
图二
图三
图四
问题
#include<stdio.h>
int main()
{int n = 1;int m = 2;switch (n){case 1:m++;case 2:n++;case 3:switch (n){//switch允许嵌套使用case 1:n++;case 2:m++;n++;break;}case 4:m++;break;default:break;}printf("m = %d, n = %d\n", m, n);return 0;
}
答案:
分析:(1)-》(2)-》(3)-》(4)-》(5)
(1)先执行外面的swtich,n为1,执行case 1,后m=3.因为其后无break,进行执行case。
|
(2)执行case 2-》m=3,n=2.
|
(3)执行case 3->,执行内嵌的switch中的case 2-》m=4,n=3,遇到break,跳出内部switch
|
(4)执行case 4-》m=5.遇到break,跳出外部switch;
|
(5)m=5,n=3;
|
3.4.3循环结构:while,do while,for循环;
1.while语句形式
while(表达式){语句体}
当表达式为真是,执行语句体.
2.do …while语句形式
do{语句体}while(表达式);
先执行语句体,后判断表达式
3.for语句形式
for(表达式1,表达式2,表达式3)
表达式1:
表达式1为初始化部分,用于初始化循环变量的。
表达式2:
表达式2为条件判断部分,用于判断循环时候终止。
表达式3:
表达式3为调整部分,用于循环条件的调整。
注意
1.while的执行条件始终比循环体多一次。
|
2.do while语句注意语句结束要有分号"";“,且其循环体始终与表达式执行次数一致。
|
3.brake只能跳出一层循环(当内循环结构时,只能跳出内部一层循环结构)
|
4.continue只能跳出本次循环。
|
练一练
打印9*9乘法表
for()形式
int main()
{int i = 0;int j = 0;for (i = 0; i < 10; i++)for (j = 1; j <= i; j++){printf("%d*%d=%-2d", i, j, i * j);if (j == i)printf("\n");}return 0;}
分析:通过i控制行,j控制列.
while形式
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
int main()
{int i = 1;int j = 0;while (i < 10){j = 1;while (j <= i) {printf("%d*%d=%-3d", i, j, i * j);j++;}printf("\n");i++;}return 0;
}
分析:外层循环控制行,层控制列
do while形式
int main()
{int i = 1;int j = 0;do{j = 1;do{printf("%d*%d=%-3d", i, j, i * j);j++;} while (j <= i); printf("\n");i++;} while (i<10);return 0;
}
分析:外层循环控制行,层控制列
3.5函数
背景:在一个main函数中,我们可以通过代码的形式完成某些目的,但是这样,main函数就会变得很长。为了尽可能的减少main函数的代码长度,我们创建函数来完成这部分工作。
|
函数形式:
返回值类型+函数名+(形参1,形参2,…)
#include<stdio.h>
int add(int x,int y)
{return x+y;
}
int main()
{int a = 0;int b = 0;int c = 0;scanf("%d%d",&a,&b);c=add(a,b);printf("%d\n",c);return 0;
}
函数声明形式:
返回值类型+函数名+形式类型+”;“
#include<stdio.h>int main()
{int add(int x,int y);//函数声明int a = 0;int b = 0;int c = 0;scanf("%d%d",&a,&b);c=add(a,b);printf("%d\n",c);return 0;
}
int add(int x,int y)
{return x+y;}
注意
1.自定义的函数要有返回值.
|
2.自定义的函数可以放在main函数的前面,或者后面(在后面的时候,要在main函数中提前声明)。
|
3.实参传递数据到形参时,参数类型要相同,不然会丢失部分数据。
|
3.7数组
背景:如果我们想存储一组数,我们一个怎么办呢?这时候即需要c中的数组;
|
3.7.1数组的定义:
数组元素类型+数组名+【数据数量】;
int arr[10]={1,2,3,4,5,6,7,8,9,10};
3.7.2数组下标:
int arr[10]={1,2,3,4,5,6,7,8,9,10};
数组长度是10,下标从0~9;
3.7.3数组的使用
#include <stdio.h>
int main()
{int i = 0;
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
for(i=0; i<10; i++)
{printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
注意
1.数组下标小于数组长度,且其最大值为数组长度-1;
|
2.数组名是数组的首地址;
|
看题
下面程序有问题吗?
#include<stdio.h>
int main()
{ int i = 0;int arr1[10]={0};char arr2{10}={0};char arr3[10]={'0'};printf("%d\n",arr1[0]);printf("%c\n",arr2[0]);printf("%c\n",arr3[0]);return 0;
}
分析:
arr1[0]被初始化为0;arr2[0]被初始化为0;arr3[0]被初始化为字符’0’;
|
0 对于int 型 就是数字0,但对char ,在ASII表中是 空 的意思,即没有任何意义(NULL)。
|
字符’0’对于char 型是字符串结束标志。
|
|
3.8操作符
3.8.1算术操作符:
+,-,*, /,%
注意
除法的2种情况:
|
/的前后都是整形数据时,对结果取整。
|
/的前后存在浮点数时,结果就是浮点数。(图一)
|
#include<stdio.h>
int main()
{int a =0;
int b =0;
int c2 =0;
float c2 =0;
scanf("%d%d",&a,&b);
c1=a/b;
c2=a/b;
printf("%d\n",c1);
printf("%f\n",c2);return 0;
}
3.8.2位移操作符:
<<,左位移操作符
>>右位移操作符
它们移动的是补码
补码补充
1.计算机在内存中处理数据,都是按数据的补码形式进行运算的,最后以原码的形式表现数据。
|
2.正数与0的,原码,反码,补码是一样的。
|
3.负数的原码是按正数编时的二进制原码;反码是原码除符号位,其它位取反;补码是反码+1。
|
题目
#include<stdio.h>
int main()
{int a=-1;int b=-1;printf("%d\n",a<<2);printf("%d\n",b>>2);return 0;
}
3.8.3位操作符:&,|,^
注意
运算符
|
功能
|
运算规则
|
&
|
按位与
|
对应位均为1时,才位1,否则为0
|
|
|
按位或
|
对应位存在1时就为1
|
^
|
按位与或
|
对应位相同为0,相异为1
|
<<
|
左移
|
补码左移若干位,超出丢弃(不包括1),剩下补0,每左移一位,相当于多乘2;
|
>>
|
右移
|
补码右移若干位,正数左补0,负数左补1,右边溢出丢。
|
3.8.4赋值操作符:=,+=,-=,*=,/=,&=,|=,<<=,>>=
3.8.5单目操作符:
单目操作符表
单目操作福
|
功能
|
!
|
逻辑反操作
|
-
|
负值
|
+
|
正值
|
&
|
取地址
|
sizeof
|
就类型长度(以字节为单位)
|
~
|
对一个数的补码按位取反
|
–
|
前置:先自减,后应用;后置:先应用,后自键
|
++
|
前置:先自增,后应用;后置:先应用,后自增
|
*
|
间接访问操作符(解应用操作符)
|
(类型)
|
强制类型转换
|
3.8.6关系操作符:
>,>=,<,<=,==,!=;
3.8.7逻辑操作符(双目运算符):
逻辑操作符
|
功能
|
&&
|
且,只有当2边逻辑都为真是才为真
|
||
|
或,一边为真即为真
|
3.8.8条件操作符
3.8.9逗号表达式:
exp1,exp2,exp3…
注意
逗号表达式的运算结果以最后一项为准。
看图
3.8.10下标引用[],函数调用(),结构体成员->.
3.9关键字
关键字
|
功能
|
auto
|
存储类别说明关键字(局部变量)
|
break
|
终止一层循环
|
case
|
swtich语句中的case
|
char
|
字符数据类型说明关键字
|
const
|
将变量定义为长量
|
continue
|
结束本次循环,直接执行下次循环
|
default
|
switch语句中,当没有满足case的情况,默认执行default语句
|
do
|
do {}while();语句中的关键字
|
double
|
双精度数据类型说明关键字
|
else
|
与最近if匹配的else分支语句
|
enum
|
枚举变量的说明关键字
|
extern
|
提前告知变量,函数等出现在别的文件中
|
float
|
单精度数据类型说明关键字
|
for
|
for的说明关键字
|
goto
|
C语言中提供了可以随意滥用的 goto语句和标记跳转的标号。
|
if
|
分支语句说明关键字
|
int
|
整形数据说明关键字
|
long
|
更大整形说明关键字
|
return
|
返回某种类型的值,结束函数
|
short
|
短整形说明关键字
|
signed
|
有符号型说明关键字
|
sizeof
|
测定数据占内存空间的大小,单位字节
|
static
|
静态成员说明关键字(具体说明看下面)
|
struct
|
结构体说明关键字
|
switch
|
swtich分支语句关键字
|
typedef
|
重新定义数据类型别名:typedef unint unsigned int
|
union
|
联合说明关键字
|
unsigned
|
无符号整形说明关键字
|
void
|
空类型说明关键字
|
while
|
while语句说明关键字
|
register
|
|
volatile
|
|
注意
在定义变量,函数名时不能使用关键字
3.9.1static:
1.修饰局部变量:延长局部变量生命周期,不改变其作用域(图一)
|
2.修饰全局变量:改变全局变量的外联性(可被其它文件使用。extern),使全局变量只能被本模块使用。
|
3.修饰函数:改变函数的外联性(可被其它文件使用。extern),使函数只能被本模块使用。
|
图一
图二
图三
3.10#define定义宏常量和宏
#define+“空格”+宏常量名+常量
|
#define+“空格”+宏名+表达式
|
3.11指针
3.11.1内存:
内存是电脑上特别重要的存储器,计算机中程序的运行都是在内存中进行的 。所以为了有效的使用内存,就把内存划分成一个个小的内存单元,每个内存单元的大小是1个字节。为了能够有效的访问到内存的每个单元,就给内存单元进行了编号,这些编号被称为该内存单元的地址。
|
3.11.2内存是怎么被编号的?
我们知道32位计算机有32根物理地址线(通过地址线,寻找相应地址的数据),在通电时,每根电信号被转化为1/0。而这样的32跟地址线,可形参232种不同的32为位二进制编码。二232字节换算成G时为4G,在32为系统4G内存足够了。因此以这 232种二进制(其实是将二进制转化为16进制,编号内存的)为编号刚好,(另外通过增加地址线的方法,可以增加内存)
|
3.11.3地址的存储
3.11.4指针变量:
3.11.5指针的大小:
前面我们知道,32系统下的32为地址线,通过32位二进制编号内存,所以在内存中我们存储一个地址时需要4个字节的内存单元,即32位下指针大小为4字节。同理64位系统下,指针大小为8字节
|
3.11.6补充
我们在定义变量时,随机存储在内存中。当程序结束时,变量内存释放。每次运行,变量都随机存储于内存中。
|
3.12结构体
前言
对于人这个抽象概念,我们很模糊,但我们具体到某个人时,他的名字,性别等,做为他的具体属性被我们知道。
|
因此我们定义结构体,用于对具有共同属性的一类事物的抽象
|
3.12.1结构体定义:
struct+结构体名
{
属性1;
属性2;
…
};
注意
1.定义结构体不可丢关键字struct
|
2.结构结尾的分号不能丢
|
3.12.2结构体数组:
| ------------------------------------------------------------ |
感言:
1.对目前c语言的有些地方学的不深,不敢过多描述。哈哈。
2.在这段学习中,我会了一些小游戏,由其是关机程序,贼有意思!哈哈。后面会补上的。
3.《高质量的c-c++编程》PDF版链接:链接:https://pan.baidu.com/s/1yW6FgsZDqeOtVzePrdZk_Q
提取码:2021
c生万物之初识c语言相关推荐
- 【C生万物】 初识篇(01)
欢迎来到 Claffic 的博客
- 【C生万物】 初识篇(02)
欢迎来到 Claffic 的博客
- c生万物【第一章 初识c语言】
c生万物---第一章 初识c语言 前言 1.什么是C语言 2.第一个C语言程序 3.数据类型 4.变量.常量 4.1定义变量的方法 4.2变量的分类 4.3变量的使用 4.4 变量的作用域和生命周期 ...
- 太阳系c语言代码大全,C生万物,编程之本!
无极生太极,太极生两仪,两仪生四象,四象生八卦,八卦演万物.而C语言在编程界地位丝毫不逊色于"太极"! C语言从出生之时已被赋予"神圣使命",这个使命便是向下要 ...
- 【C语言航路】第一站:初识C语言(四)
目录 十一.关键词 1.常见关键词总结及分类 (1)类型 (2)循环 (3)选择分支 (4)其他 2.关键词register 3.关键词typedef 4.关键词static (1)修饰局部变量 (2 ...
- C语言初阶_初识C语言(1)
凡是过往,皆为序章 期末考试结束了,真是感慨良多啊...... C语言编程题大家都做对了多少呢? 不管怎么样,都已经过去了.不管你学得怎么样,都可以在接下来的时间里,我们一起重新回顾一遍C语言初阶的知 ...
- 梦开始的地方----初识c语言(1)
目录 前言 一.c语言是什么? 二.初识C语言 1.打印hello world 2.数据类型 3.常量与变量 三.结束语 前言 Hello!!!我又来了,从今天开始就要从头开始学习c语言了,想要一块学 ...
- 请回答c语言-初识c语言(上)【入门】
请回答c语言-初识c语言(上)[入门] 1.为什么我们要学习c语言? 2.什么是C语言 3.第一个C语言程序 4.利用编译器 5.数据类型 6.常量与变量 6.1变量的定义方法 6.2局部变量和全局变 ...
- C语言入门(初识C语言)
C语言入门(初识C语言) 前言 什么是C语言? 为什么选择C语言? 计算机语言的发展 高级计算机语言中的经典:C语言 初识C语言(正片开始) 一.第一个C语言程序(你好,C语言) 1.1 #inclu ...
最新文章
- Servlet学习-request
- python基础练习(三)
- 深入理解JVM虚拟机(十):Java内存模型与多线程
- C++计算nCr模p表达式如n! / (r! * (n-r)!)的实现算法(附完整源码)
- 如何在Ubuntu上创建桌面快捷方式
- C++ 深拷贝与浅拷贝
- python----流程控制
- 12、scala函数式编程集合
- 从React 编程到好莱坞
- 使用Github Actions构建、发布和部署NuGet软件包
- ros openwrt 分流_常平:推进“截污大会战”补贴助力企业雨污分流
- 如何控制Asp.net Login控件的重定向地址
- java jdk学习_Java学习第一步:JDK环境搭建(纯小白向)
- 亲邻门禁卡复制数据分析
- Anaconda 更新pip等库
- 这年代,你需要了解一下什么是聚合搜索(附站点推荐)
- 4r照片尺寸是多大_数码照片4D、4R、6RW是什么意思?4R照片尺寸是多大图片?
- 请问苹果x是如何建文件夹_苹果xmind怎么建立文件夹
- 人工智能课后作业_python实现广度优先遍历搜索(BFS)(附源码)
- 从西工大图书馆校外下载论文方法
热门文章
- 文件的打开和关闭,fopen()和fclose
- 软件测试团队收获,软件测试中如何团队合作才能和谐?
- 前端面试必会 | 一文读懂 JavaScript 中的 this 关键字
- 怎么通过在线PS修图 修图工具有什么
- 高校网络营销课程大改迫在眉睫
- mysql 授予数据库权限_MySQL:授予**对数据库的所有**权限
- wampserver 2.4 配置虚拟主机
- IT行业对学历要求如何?
- Apache配置及应用
- android+后台日志开启,Windows 下查看Android手机日志(LogView使用)