C基础入门
第一天(数据类型与运算符):
(1)对基本数据类型的了解:
在32 位的系统上short 咔出来的内存大小是2 个byte;
int 咔出来的内存大小是4 个byte;
long 咔出来的内存大小是4 个byte;
float 咔出来的内存大小是4 个byte;
double 咔出来的内存大小是8 个byte;
char 咔出来的内存大小是1 个byte。
大致知道他们的取值范围,因为在赋值时会出现溢出现象;
(2)对操作符的了解(只举经常用到的):
+,-,*,/ 不解释;
%(重点)用于求余;(给我写一个水仙花数来练练这个求余(搜搜什么是水仙花数))
{
int i=15;
int j;
j=15%10;
//此时j为5
}
= 赋值运算符(不是等号)
== 这个是等号
!=这是不等号
>=,<=不解释
++,--运算符(重点)
把这个运算恨敲几遍,搞懂,至少3遍;
{
int i=0;
int sum;
sum=i++;
//此时运算顺序是先把i赋值给sum,然后i+1;
sum=++i;//此时的运算顺序是i+1后再赋值给sum;
}
||,&&这两个了解下,前一个是或逻辑,后一个是与逻辑,
{
int i=2,j=5;
(i>0||j>10)//此时是true;
(i>0&&j>10)//此时是false
}
-=,*=,/=,+/这些玩意纯属造出来扯淡,不直观
sum-=i相当与sum=sum-i;//其他的一样,不解释;
&取地址运算符,先了解下,后面会说;
a?b:c这个最牛*了,太喜欢了,判断a,如果a为true,则取b,反之取c;
{
int i=0,j=2;
int result;
result=(i<j)?j:i;//判断i是否小于j,如果是就把j赋值给result,反之就把i赋值给result;
}
(3)对数据的隐式和显式转换(不做重点,以后遇到问题了可以加个显式转化试试);
隐式就是系统自动给你转换了
{
float i;
int j;
(j+i)//这两个数加起来就被自动转换为float类型
}
所谓显式转化就是在一个数据前面加一个数据类型,
int i;
(float)i//此操作就把i转换为了float类型
...........................................................................................................
几道题(自己写,没思路的时候去敲helloworld去,等敲的很有成就感想这个):
做这些程序时别用调用函数,就在main里干
1.水仙花数
2.搞几遍--,++运算符的原理
3.对a?b:c的理解
4.多敲敲第(1)中的数据类型,看看怎么会溢出
............................................................................................................
第二天(几种操作运算符)
(1)for
对于for循环,这很使用,它无处不在,可以不知道while,但必须知道for,
主要用法就是
for(i;j;k)这个形式;
{
for(int i=0;i<100;i++) //这个是对i进行递加
{
//dosomething
}
for(int i=100;i>0;i--)//这个是对i进行递减
{
//dosomething
}
}
(2)if else
对于 if ....else主要是判断用的
主要形式就是
{
if(int i>0)
{
//dosomething;
}
else
{
//dosomething;
}
}
当然形式是自己吊出来的,随便套随便改;
{
if(int i>0)
{//dosomething;
}
else if(int i>10)
{//dosomething;
}
else if(int i>20)
{//dosomething;
}
else
{//dosomething;
}
}
在if或者else里仍可以嵌套if...esle,不解释
(3)while
对于while同样是带有判断的循环;
形式就是
{
while(int i>100)//直到i大于100的时候停止循环
{
//dosomething;
}
}
(4)switch() {case}
对于switch这个是个选择判断;
形式就是
{
switch(判断的参数)
{
case 判断参数1:
//dosomething;
break;
case 判断参数2:
//dosomething;
break;
......
}
}
(5)do while(至于这玩意吧,造出来也可能是个费的,没咋用过,看形式很神奇,前面还带个do)
形式就是
do
{
//dosomething;
}while(判断)
它跟while的区别就是,它先执行一次后在判断,这个在考试中貌似经常出,平时做项目没用到过;
(6)break,continue
这两个玩意,太风骚了,都是跳出,但管的范围不一样;
break常用在switch中,就是直接跳出,哥们我不干了,爱咋咋地,说的就是他;
continue常用在for或while循环中,他没break有骨气,只是偶尔的罢工,然后还得回来继续干活,他只是跳出本次循环
break在switch中的应用就不解释了,在for里看看:
for(int=0;i<100;i++)
{
if(i==10){
printf("%d",i);//执行到i=10的时候,因为break这货要罢工,这个循环就停了,只循环了10下就完了
break;}
}
再来看看continue
{
for(int i=0;i<100;i++)
{
if(i==10)
{
continue; //在这当i=10 continue罢工了一次,后面的printf语句不执行了,但是for会从i=11继续循环
}
printf("%d",i);
}
}
...........................................................................................................
几道题
1.分别用for循环,while循环,do while循环算出一个100!的结果,效果分别是1*2*3*....*100=和100*99*98...*1=
2.分别用switch和if else写出成绩评价,当i<60 打印不及格,i>60且i<80打印良,当i>80,打印优秀;
3.好好敲敲第(6)中我写的break和continue的代码,好好理解理解他们的区别
.............................................................................................................
第三天(对函数之间的调用关系)
函数之间传递的是值;
对于什么是实参,什么是形参,搞不明白算了,只要知道怎么用就够了;
第一点:
对于一般的函数调用
(1)无参调用(说白了就是把被调用的函数的语句掉到了主函数里,为什么这么做,主要是那样看着好看,主函数看着不至于
那么臃肿);
{
void print()
{
printf("hello world");
}
void main()
{
print();
}
}
(2)对于有参的一般调用
{
void print(int i)
{
printf("输出%d",i);
}
void main()
{
int j=2;
print(j);
}
}
(3)对于有返回值的带参数的一般调用(函数定义了什么返回值,最后的return类型也必须是什么类型,这个不解释)
{
int sum(int i,int j)
{
int sum;
sum=i+j;
return sum;
}
void main()
{
int n=2,m=2;
int sum;
sum=sum(n,m);
printf("输出的和是%d",sum);
}
}
上面的都是很直观的调用和很直观的参数
第二点:讲点关于传递地址和指针的玩意
(1)对于地址传递的调用;
不管在C#,C,C++,Java,还是网站语言PHP,我都碰到过这样一个典型的值传递例子,考试的话不考这个就是出题人的失职:
{
void max(int a,int b)
{
int tem;
tem=a;
a=b;
b=tem;
}
void main()
{
int m,n;
scanf("%d%d",m,n);
max(m,n);
printf("%d %d",m,n);
}
........................................................
...........................................................
void max(int &a,int &b)
{
int tem;
tem=a;
a=b;
b=tem;
}
void main()
{
int m,n;
scanf("%d%d",m,n);
max(m,n);
printf("%d %d",m,n);
}
}
运行上面的两段程序,看看运行结果,有什么区别;原因就是一个是值传递一个是地址传递
(2)对于在参数中取值的调用函数
{
void outPut(int i,int j,int *sum)
{
sum=i+j;
}
void main()
{
int m=2,n=2,i,sum;
outPut(m,n,&i);//因为outPut函数第三个函数是*sum,所以在调用是要用地址来填参
sum=i;//在这里就把m+n的值给引了出来;
}
}
(3)对于近来在数据结构中经常出现的指针参数很无奈,在这也简单的说一下
对于指针参数其实跟一般的参数一样,只是一般的参数的数据类型都很常见,一碰到了指针这个类型有点怕;
但对于什么参数类型只要知道一点就够了,被调用的函数的参数是什么类型,在调用是也同样用什么类型,这在学习java或者c#是经常只是给你方法让你填参一样;
{
struct Person
{
char name[10];
int age;
}
void print(Person *person)
{
person->name="wanghe";
person->age=20;
printf("%s%d",person->name,person->age);
}
void main()
{
Person *person=(*Person)malloc(sizeof(Person));//在这里定义了一个Person指针
print(person)//因为在print函数里就是Person指针参数,所以在这里就放入person这参数;
}
}
..........................................................................................................
至于题嘛,来一个输入一个长方体的长宽高,然后算出她的体积和各面的面积吧,要求用调用函数
.........................................................................................................
第四天:
对于数组的理解
对于数组都知道是用于原始存储数据的,它的初始索引值是0;
第一讲:一维数组:
对于一维数组就很简单了,
(1)定义数组:数据类型 变量名[数组大小];
下面主要举例对数组的具体操作:
{
int data[5];
for(int i=0;i<5;i++)
{
scanf("%d",&data[i]);
}//再此循环中对数组进行赋值
for(int j=0;j<5;j++)
{
printf("%d",data[j]);
}//在此对数组进行取值
}
当然也可以对其进行直接赋值
比如:int data[5]={1,2,3,4,5};
char data[5]={'a','b','c','d','e'};
char data[6]="abcde";//在这为什么是6呢,因为在"abcde"这个字符串中,这个是字符串有串尾结束符'\0'符,这点记住就行了;
用sizeof("abcde")可以得出是6;
(2)对于数组指针这个玩意,这个指针是指向数组的头元素:
例如:
int data[5]={1,2,,3,4,5};
怎么用指针来取它的值呢
{
int *p;
p=data;//这一步是用于去得数组的第一个元素地址
for(int i=0;i<5;i++)
{
printf("%d",*(p+i));//取得地址里的值
}
}
(3)对于数组做参数
数组做参数跟其他的数据类型没区别:
{
void print(int data[])
{
for(int i=0;i<5;i++)
print("%d",data[i]);
}
void main()
{
int data[5]={1,2,3,4,5};
print(data);
}
}
对于一维数组基础的就这些吧,扩展的玩意都可以在此基础上玩
第二讲 就是二维数组了
还是那样,对二维数组的操作还是分为三个方面(1.具体的存入取出,2.指针对他的操作,3.怎么做参数)
(1)对二维数组的存入和取出
{
//定义数组
int data[3][3];
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
{
scanf("%d",&data[i][j]);//对二维数组的循环存入数据操作
}
}
//下面进行取出操作
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
{
printf("%d ",data[i][j]);//对二维数组的循环取出数据操作
}
printf("\n");//这句换是让它成二维排列
}
}
对于普通的赋值:
data[3][3]={{1,2,3},{4,5,6},{7,8,9}};
( 2)对于数组指针这个玩意,这个指针是指向数组的第一行的第一个元素:
例如:
data[3][3]={{1,2,3},{4,5,6},{7,8,9}};
怎么用指针来取它的值呢
{
int data[3][3]={{1,2,3},{4,5,6},{7,8,9}};
int (*p)[3];//定义二维数组的指针,也叫数组指针,这里就不纠结于概念了,免得烦
p=data;
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
{
cout<<*(*(p+i)+j);//这里出现了两个指针符,里面的是取行,加个列就成准确的行列
}
}
}
可能现在还不好理解 ,等以后你敲的多了,会慢慢明白的
(3)对于数组做参数
数组做参数跟其他的数据类型没区别:
{
void print(int data[][])
{
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
print("%d",data[i][j]);
}
void main()
{
int data[3][3]={{1,2,3},{4,5,6},{7,8,9}};
print(data);
}
}
对于二维数组基础的就这些吧,扩展的玩意都可以在此基础上玩
对于数组这玩意,也不要相的太复杂,它其实就是一个存入取出的工具,你越想的复杂你越搞不懂它;
第五天:
对于结构体的理解:
其实结构体就是让你自己定义数据类型的,不是什么新鲜玩意,以前的像int float什么的是系统给你的,现在给你自由了,让你自己来玩,应该是好事,其实在往深处玩代码时,你会发现往往系统给你的东西你总是不满意,老想玩自己写的。而结构体就是C给你的想象体,也学是C太古老了吧,我没在他里面发现class这个玩意,这里就不详细说class了,有兴趣自己可以查查,比struct好用多了。
废话少说,开始玩代码:
对于结构体的定义就是:
C的标准:
typedef struct {
数据类型 变量名;
数据类型 变量名;
数据类型 变量名;
数据类型 变量名;
.
.
.
}结构名;//最后的这个“;”符号不能掉;
C++就自由多了:
struct 结构名{
数据类型 变量名;
数据类型 变量名;
数据类型 变量名;
数据类型 变量名;
.
.
.
};
对于结构体到底占多少了字节,那就是它里面定义的所以数据类型占的字节数总和;
对于结构体的用法,应该都不陌生:
{
typedef struct
{
char name[10];
int age;
}Person;
void main()
{
Person person;
scanf("%s%d",&person.name,&person.age);
printf("%s%d",person.name,person.age);
Person *p;
p=&person;//去person的地址
printf("%s%d",p->name,p->age);
}
}
当然也可以对结构体进行嵌套:
typedef struct
{
char name[10];//姓名
int age;//年龄
}Person;
typedef struct
{
Person person;//嵌套个结构体person;
int num;//学号
}PersonMsg;
void main()
{
PersonMsg personmsg;
//怎么对它进行赋值,看好了
personMsg.person.name="wanghe";
personMsg.person.age=20;
personMsg.num=123456;
//当然取值是也是一样
}
关于指针对他的操作就还是上面的玩意,没新意;
结构体很简单,不要想复杂,就这几个操作;
第六天 指针(其实也不能算是一个很多的题目)
对于指针这玩意,也就在C或C++里看到,在C#,java,或者别的玩意里我都没见到,也确实没有,因为这玩意太危险,所以后来发展的高级语言都摒弃了,指针就想是一把枪,本来是要崩别人的,但是指向这个,再指指那个,最后拿枪的自己给自己给崩了,因为他也不知道到底指向了谁;
(1)指向普通类型;
比如 int ,float等;
int i;
int *j;
j=&i;//在这里把指针指向了i的地址,这个地址名字叫j;
*j=2;//为指向的地址的变量赋值
(2)指向数组;这个在讲数组时说过了;
(3)指向结构体,这个也讲过了;
下面讲讲,指针在函数调用是的主要作用:
由于指针是指向一个变量的地址,所以就确定了位置,不会变,能够确定操作的准确性,主要原因还是双向传递,互通的,而不是单单的单向值传递:
对于在函数调用那节的那个例子就很经典:
{
void max(int a,int b)
{
int tem;
tem=a;
a=b;
b=tem;
}
void main()
{
int m,n;
scanf("%d%d",m,n);
max(m,n);
printf("%d %d",m,n);
}
运行结果:
2 3
输出 2 3
........................................................
...........................................................
void max(int &a,int &b)
{
int tem;
tem=a;
a=b;
b=tem;
}
void main()
{
int m,n;
scanf("%d%d",m,n);
max(m,n);
printf("%d %d",m,n);
}
运行结果:
2 3
输出 3 2
}
第一个就是单单的值传递,在mian函数里调用max函数,只是把m,n穿到了max里,但肉包子打狗,max也确实完成了任务但就是穿不过来
第二个就不一样了,进行的是地址传递,在m,n传给max函数是,同时max还取得了m,n的地址,max在地址里把事就干了,完成了互通;
对于在数据结构中出现的返回类型为指针类型的,说白了跟返回int类型一样:
举个例子
{
typedef struct
{
int num;
int age;
}Person;
*Person getPerson()
{
Person *p;//在这里p是个指针吧,等会就把它给返回了;
Person person;
p=&person;
p->num=12;
p->age=12;
return p;
}
void main()
{
Person *p;
p=getPerson();
//这时得到的p->num就是12,p->age也是12;
}
}
指针也不会玩太难的,就是这些基础;
关于C的基础就这写吧,可能还有些琐碎的东西没点到,在学习的时候做参考吧,还是那句话,玩代码玩的就是熟练,多敲,如果只是为了考个试,少敲也无可厚非;