黑马程序员—01C语言拾遗

来源:互联网 发布:和室友网络冲突怎么办 编辑:程序博客网 时间:2024/05/16 00:27

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------


以前学习过c语言,对c语言语法之经典钦佩至极。后因学校课程安排原因,竟时隔多年未曾接触之。近日获李明杰老师c语言基础班视频资源,欣喜观之,有温故知新之效。下面,仅将知新之内容,以c语言拾遗为题叙之。


一、include简单使用

1> 作用 :

拷贝右边文件的所有内容到#include所在的位置。

自定义的文件用" ",系统自带的文用<>


2> #include<stdio.h>的目的 :

* 拷贝printf 等函数的声明。


3> 举例 :

#include<stdio.h>#include "zcb.txt"#include "/Users/apple/Desktop/zcb.txt"


4> 心得 :

以前只是死板的记着,凡是c语言程序,第一行一定要写#include<stdio.h>,程序中使用到了字符串的内容,就多写一行#include<string.h>,或者用到数学知识了就再多写一行#include<math.h>等等。

现在看来,include的作用是拷贝,当程序需要调用某些函数时,便拷贝这些函数的声明所在的文件。当拷贝系统定义的文件时,用<>,当拷贝自定义的文件时,用“ ”。并且,“ “里面可以是系统文件目录下的自定义文件名,也可以是自定义的文件名的路径。


二、return的简单说明

1> 作用:

* 退出函数。

* 返回一个具体值给调用者。


2> 注意点:

* void代表没有返回值。

* 如果没有明确说明返回值类型,将默认返回int型。

* 就算明确的说明了返回值的类型,也可以不返回任何值。


3> 举例:

1.void test1(){printf("I am zcb \n");} // void型,不返回任何值。
2.int test2(){printf("I am zcb\n");}// int 型,但未返回任何值。

3.int main(){return 0 ; // 程序结束处}
4.double test3(double a, double b){return a + b;} // 可以返回表达式。

4> 心得:

从字面意思上来看,return 返回的意思,在每个程序的末尾,或者在有返回值的函数末尾使用。此为以前从未在意过的知识点,被李老师扫盲了...惭愧!

三、break和continue

1> break :

1. 使用场合:

* switch语句,退出整个switch语句。

循环结构,退出整个循环语句。譬如:while do whilefor语句当中。

2.注意点:

只对最近的循环体结构。

2> continue:

1. 使用场合:

循环结构,退出当前的循环趟。譬如:while do whilefor语句当中。

2. 注意点:

只对最近的循环体结构。

3> 举例:

/**********break*********/switch (score/10){case 10: // 100case 9: // 90+case 8: // 80+case 7: // 70+case 6: // 60+      printf("及格\n");      break; // 这里的break,指满足 score/10的以上case执行到这里以后,退出switch。default:      printf("不及格\n");      break;}

/********continue*********/int main(){int i,j;for (i = 0; i<3; i++){for (j = 0; j<2; j++){if (j==1){continue; // 这里的continue指满足j==1的话退出for(j=0;j<2;j++)这层j==1的循环,进行下一场循环}printf("A");}  printf("B"); }return 0;}输出结果:ABABAB

4> 心得:
印象中的break和continue都是打断循环,而break是打断整个循环、结束循环的意思;而continue是中断当前这次循环,进行循环体内下一轮的循环。从李老师视频中又学习到这两个关键字的打断循环的功能是就近原则的,也就是说他俩是有作用范围的,而不是针对整个程序,只是打断其所在的循环体或switch而已,这次的break和continue的“温故”使我更加深刻、也更加深入的理解了这两个关键字。



四、进制的转换—输出二进制的存储形式
1> 进制 :
进制也就是进位制,是人们规定的一种进位方法。 对于任何一种进制---X进制,就表示某一位置上的数运算时是逢X进一位。 十进制是逢十进一,十六进制是逢十六进一,二进制就是逢二进一,以此类推,x进制就是逢x进位。
几乎所有语言最终翻译给机器执行的时候,都会翻译成二进制,二进制是计算技术中广泛采用的一种数制。如果在编程的过程中巧妙的运用了二进制或者位的运算,就会提高程序执行的效率。

2> 数据类型在内存的存储方式 :
基本的数据类型和长度: int 4; long 4; short 2; signed char 1; unsigned char 1; unsigned long 4; unsigned short 2; float 4; double 8 ;指针 8。然后就是每个字节占八个位,每个位为‘0’或者‘1’。内存就这样存储着各种数据。

3> 举例 :
int main(){    void putBinary(int);        putBinary(-12);        putBinary(13);    return 0;}void putBinary(int n){    int bits = sizeof(n) * 8;    while (bits-->0){        printf("%d", n>>bits&1);        if (bits%4==0) printf(" ");    }    printf("\n");}输出结果:1111 1111 1111 1111 1111 1111 1111 0100和0000 0000 0000 0000 0000 0000 0000 1101


4> 心得 :
此算法为十进制的数在内存中存储方式!用此算法可以输出int型的十进制数在内存中的表现形式。算法用到了位的运算,说起来今天的收获最大的莫过于位运算了,之前学c语言把指针当作“主干”,位运算这些“枝叶末梢”并未放在心上,今天学完内存管理这节内容,才由衷的发现内存的重要性、进制操作、位操作的重要性!下面,将关于位运算的琐碎知识整理一下:
* & : 按位与。只有对应的两个二进位均为1时,结果位才为1,否则为0。二进制中,与1相&就保持原位,与0相&就为0。

* | : 按位或。只要对应的二个二进位有一个为1时,结果位就为1,否则为0。

* ^ : 按位异或。当对应的二进位相异(不相同)时,结果为1,否则为0。相同整数相^的结果是0。多个整数相^的结果跟顺序无关。

* ~ : 按位取反。对整数a的各二进位进行取反,符号位也取反。

* >> : 右移。把整数a的各二进位全部右移n位,符号位不变。右移n位其实就是除以2的n次方。正数的高位补0,负数的高位补啥由系统决定。

* << : 左移。把整数a的各二进位全部左移n位,高位丢失,低位补0。左移n位其实就是乘以2的n次方。可能会改变正负性。


五、数组的定义(一维数组为例)
1> 数组

数组就是用来存储一组数据的,而且只能存放一种类型的数据。


2> 格式
type 数组名[元素个数]。这里访问某个元素时,比方说访问第i个元素,直接“数组名[i]”就行啦。

3> 举例
// 这些是正确的写法 int ages[5] = {10 , 11, 12, 67, 56}; // 五个元素,依次为10,11,12,67,56 int ages[5] = {10, 11}; // 五个元素,依次为10,11,0,0,0 int ages[5] = {[3] = 10, [4] = 11}; // 五个元素,依次为0,0,0,10,11 int ages[] = {10, 11, 14}; // 虽然没写元素个数,但从后面赋值可知,是三个元素,依次为10,11,14</span>
// 错误写法int a[]; // 没写元素个数int a={10,11,12}; // a是整形变量,不能是数组int count=3;int a[count]={10,11,12}; // 这样写不对,虽然count=5,但是变量名不能当作数组元素里的

4> 心得
听说数组的定义千奇百怪,稍有不慎,就会定义错!所以一直以来,我都是采用最“保险”的数组定义法:type 数组名[元素个数];然后再进行赋值操作的。我也曾在网上专门找数组定义的总结,但始终无果,幸好听到李老师关于数组的专门总结才让我茅塞顿开!各种正确的、错误的定义法几乎都列举出来了,算是学的新知识了。


六、字符串的定义
1> 字符串
很多字符组合在一起就是字符串了。字符用‘ ’(譬如:‘A’为字符A);字符串用“ ”(譬如:“A”为字符串A),字符串与字符不同的是,字符在内存中占一个字节,而字符串是占了字符总个数个字节,然后加上‘\0’这个字符。

2> 字符串的定义方式
* 利用数组 :字符串里面的字符是可以修改的,使用在字符串里的字符经常修改的情况下!
* 利用指针 :字符串其实就是一个常量字符串,里面的字符不能修改,使用在这个字符串不用修改,并且经常用他!

3> 举例
int main(){char a[4] = "zcb"; // 这里利用数组a[2] = 'h';printf("%s\n",a);return 0;}
int main(){char *a = "zcb"; // 这里利用指针printf("%s\n",a);return 0;}</span>

4> 心得
以前定义字符串,一直用数组,方法如下:
int main(){char a[80]; // 这里利用数组,长度是80,一般够用了。gets(a); // 这里的gets()是输入字符串并显示到屏幕上。printf("%s\n",a);return 0;}
对于利用指针定义字符串,只是在函数中见到过,并未自己用过,属于见到认识、不知道名字的方法,是似熟非熟的那种知识,这是我c语言基础知识的新发现,也拓展了我对指针和字符串的新认识,对我以后灵活定义字符串很大帮助!


七、指向函数的指针
1> 指向函数的指针
函数作为一段程序,在内存中也要占据部分存储空间,它也有一个起始地址,即函数的入口地址。函数有自己的地址,我们的指针变量就是用来存储地址的。因此,可以利用一个指针指向一个函数。其中,函数名就代表着函数的地址。

2> 定义及注意
* 定义 :函数的返回值类型 (*指针变量名)(形参1, 形参2, ...); 例如:int (*p)(int a,int b);
* 注意 :指针存的是函数地址,所以这里的指针做加减运算是没有意思的,指向函数的指针变量主要有两个用途:一是调用函数,二是将函数作为参数在函数间传递。

3> 举例
int main(){void test(); // 这个是函数的声明{void (*p)();p = test;p();} // 这是利用指向函数的指针来调用函数{test(); } // 这个是直接调用函数return 0;}void test(){printf("我要调用test啦\n");}


4> 心得
知识盲点!!!大一学c语言的时候因“不是考试重点”而忽略的重点知识!当时把指针看的很重要,但是指针章末的指向函数的指针的遗漏确实是一大损失,因此,看李老师视频的时候,这个知识点格外的陌生,不过还好,指针的其他应用我掌握的还不错,所以指向函数的指针这点我下了半天功夫,再加上李老师的讲解,现在已经搞明白啦。


八、内部函数和外部函数
1> 内部函数 
* 概念 :定义的函数只能被本文件访问使用,其他文件不能访问使用。
* 定义 :static 返回值数据类型 函数名 (参数1,参数2。。。)
* 说明 :static 不能省略。

2> 外部函数
* 概念 :定义的函数能被本文件和其他文件使用和访问,默认情况下,所以有函数都是外部函数 。
* 定义 :extern 返回值数据类型 函数名 (参数1,参数2。。。)
* 说明 :extern 可以省略,默认的就是外部函数。

3> 举例
内部函数举例:
int main(){static void test();void (*p)();p = test;p();}static void test(){printf("我要调用内部函数test啦\n");}</span>

外部函数举例:
int main(){extern void test();void (*p)();p = test;p();}extern void test(){printf("我要调用外部函数test啦\n");}


4> 心得
知识盲点!当初学c语言基础的时候,没做过大的c语言项目,所以的程序代码练习都是在一个文件里写的,所以就从来没考虑过外部函数和内部函数这种情况,现在知道了,大项目一般都是很多程序员分工合作完成的,这个时候非常考验一个优秀程序员的团队合作能力,所以,程序中个每一个变量、每一个函数、他们的属性都应该严格标明!static和extern这两个函数的属性是知识盲点,谨记之。

九、交换两个变量的三种方法!
1> 问题描述 :
两个变量a,b,用三种方法交换a,b的值。

2> 三种思路 :
* 定义一个中间变量t,将a的值赋给t,b的值赋给a,t的值再赋给b,完成a,b两个变量的值的交换。
* 通过符号的巧妙:a=b-a;b=b-a;a=a+b;即可完成交换。
* 通过位运算的巧妙:a=b^a;b=b^a;a=a^b;即可完成交换。

3> 三种算法 :
int main(){int a=10,b=20;int t;{t=a;a=b;b=t;} // 定义中间变量。return 0;}
int main(){int a=10,b=20;{a=b^a;b=b^a;a=a^b;} // 利用位运算的巧妙return 0;}
int main(){int a=10,b=20;{a=b-a;b=b-a;a=a+b;} // 利用加减法的巧妙return 0;}

4> 心得 :
三种代码各有长处,第一种方法利用中间变量,虽然占得内存大了点,但是便于程序员之间交流;第二种、第三种没用使用中间变量,显然性能上要比第一种方法好,然而却难易理解,不利于程序员之间的沟通。一般大家很难想到后两种办法!尤其是第三种位运算,性能上最好,但是却最难让人想到!听李老师讲这是应付面试的,无语额,反正记下来吧!也算是写程序时练习自己要有不同的思考方式!








0 0
原创粉丝点击