c语言笔记

c语言笔记
c语言笔记

1. 编译和链接

将程序转化为机器可执行的代码,C语言分为三个步骤:

A. 预编译。程序首先会交给预处理器,预处理器执行以#开头的指令,然后给程序添加指令,或者修改指令。

B. 编译。修改后的程序进入编译器,编译器会把程序翻译成机器指令(也就是目标代码),但是这样的程序还是不能执行的。

C. 链接。链接器把由编译器产生的目标代码和其他所需的代码整合到一起,这些附加代码包括程序中用到的库函数。这样就产生了完全可执行的程序。

2. main函数中的exit和return

在main函数中,以两者结尾是一样的。都是终止程序执行,并且向操作系统返回0。

不过exit需要引入stdlib.h库函数。

#include

#include

int main (void)

{

printf("Hello world");

exit(0);

//return 0;

}

3. %i和%d

在printf中使用时,两者没有区别,但是在scanf中,%d只能接受10进制的整数。

但是%i还可以接受八进制和十六进制的整数。

#include

#include

int main (void)

{

int i ;

scanf_s("%i",&i);

printf("%d",i);

}

4. scanf函数

scanf本质上是一种“模式匹配”函数。

但是在Visual Studio中调用scanf函数时会给出这样的提示:The function may be unsafe.Please using scanf_s instead.

当用户从键盘输入时,程序并没有读取输入,而是把用户的输入放在一个隐藏的缓冲区中,由scanf来读取。因此如果用户输入了多余的字符,scanf无法彻底完成模式匹配,scanf 就会把字符放回缓冲区供后续scanf函数的读取。

1. 编译和链接

将程序转化为机器可执行的代码,C语言分为三个步骤:

A. 预编译。程序首先会交给预处理器,预处理器执行以#开头的指令,然后给程序添加指令,或者修改指令。

B. 编译。修改后的程序进入编译器,编译器会把程序翻译成机器指令(也就是目标代码),但是这样的程序还是不能执行的。

C. 链接。链接器把由编译器产生的目标代码和其他所需的代码整合到一起,这些附加代码包括程序中用到的库函数。这样就产生了完全可执行的程序。

2. main函数中的exit和return

在main函数中,以两者结尾是一样的。都是终止程序执行,并且向操作系统返回0。

不过exit需要引入stdlib.h库函数。

#include

#include

int main (void)

{

printf("Hello world");

exit(0);

//return 0;

}

3. %i和%d

在printf中使用时,两者没有区别,但是在scanf中,%d只能接受10进制的整数。但是%i还可以接受八进制和十六进制的整数。

#include

#include

int main (void)

{

int i ;

scanf_s("%i",&i);

printf("%d",i);

}

4. scanf函数

scanf本质上是一种“模式匹配”函数。

但是在Visual Studio中调用scanf函数时会给出这样的提示:The function may be unsafe.Please using scanf_s instead.

当用户从键盘输入时,程序并没有读取输入,而是把用户的输入放在一个隐藏的缓冲区中,由scanf来读取。因此如果用户输入了多余的字符,scanf无法彻底完成模式匹配,scanf 就会把字符放回缓冲区供后续scanf函数的读取。

1. C语言中的布尔类型

在C语言中,是没有布尔类型的,0就是false,非0就是true。

于是,写习惯了Java/C#的我们自然会很不习惯,这个时候,我们不妨用宏定义来使我们的代码看起来更舒服一些。

1.#define BOOL int

2.#define TRUE 1

3.#define FALSE 0

4.

5.int main (void)

6.{

7.BOOL flag=TRUE;

8.if(flag)

9. {

10. printf("true");

11. }

12.else

13. {

14. printf("false");

15. }

16.}

在C99中,长期缺乏布尔类型的问题得到的解决,但是在目前,C99标准还没有得到很好的推广。暂且不提。

2. limits.h

习惯了平台无关的我们,在学习C语言时,必须需要注意他的平台相关性。其中很典型的例子就是在不同的平台下,不同的编译器下,int的取值范围是不同的。

在C#中,我们可以用Int32.MaxValue来获得,那么在C语言中,我们该怎么获得呢?

在C中,提供了一个头文件limits.h,里面有很多宏定义。

那么我们就很容易得到int类型的取值范围。

1.#include

2.#include

3.#include

4.

5.int main (void)

6.{

7. printf("int的最小值是:%d;最大值是:%d",INT_MIN,INT_MAX);

8.return 0;

9.}

3. 浮点类型

在C语言中,提供了三种浮点类型:分别为

float:单精度浮点数,

double:双精度浮点数,

long double:扩展精度浮点数。

在一般要求不严格的情况下,float就足够了,其次是double,long double几乎不会用到。

在C99中,浮点类型包括两种,分别为实浮点类型,就是我们上面提到的。还有复数类型,分别对应为float_Complex等等。

4. 字符类型

在C语言中,一般采用的ASCII编码,而字符类型又分为有符号型和无符号型。在C语言标准中,对此并无规定,因此是由不同的编译器自己决定。

因此考虑到可移植性,如果涉及到符号相关,我们不要假设char是有符号还是无符号,而用signed和unsigned来显式标识。

由于在C语言中,字符实际上是被作为整数来处理的,因此在C89中,将字符类型和整数类型统称为整值类型。

C语言读入字符不会跳过空白字符。我们可以看一个简单的例子:

1.int main (void)

2.{

3.char ch;

4. scanf("%c",&ch);

5. printf("%c",ch);

6.return 0;

7.}

我现在键入一个换行:

他也把换行符读入,然后打印出来。

那么我们如何读入一串字符串呢?

1.int main (void)

2.{

3.char ch='a';

4.int count=0;

5.do

6. {

7. scanf("%c",&ch);

8. count++;

9. }while(ch!='\n');

10. printf("%d",count-1);

11.}

当然,我们也可以这样来写:

1.int main (void)

2.{

3.char ch='a';

4.int count=0;

5. scanf("%c",&ch);

6.while(ch!='\n')

7. {

8. count++;

9. scanf("%c",&ch);

10. }

11. printf("%d",count);

12.}

5. getchar和putchar

在C语言中,为我们提供了专门输入和输出字符的函数,也就是getchar()和putchar().让我们看下getchar()和putchar()的定义。

_Check_return_ _CRTIMP int __cdecl getchar(void);

_Check_return_opt_ _CRTIMP int __cdecl putchar(_In_ int _Ch);

我们可以看到,其实他们返回的都是int类型的值。OK,让我们看看他们都返回什么。

1.int main (void)

2.{

3.char c;

4.int result;

5. c=getchar();

6. result = putchar(c);

7. printf("\nc:%c;result:%d",c,result);

8.}

我们可以看到,他们都是返回其字符的ASCII码。

那么,既然C语言为我们提供了这样专门的函数,一定说明他在读取和输出字符方法比scanf 和printf有着特殊的优势。

A. 由于getchar和putchar函数实现比较简单,因此较之效率更高。

B. 为了额外的效率提升,通常getchar和putchar都是作为宏来实现的。

总之,他们相较之略显重量的scanf和printf效率更高。

另外,我们还可以用getchar来实现读取字符的C语言惯用法。

1.int main (void)

2.{

3.while(getchar()!='\n');

4.return 0;

5.}

这样的函数一直读到换行终止。

另外:

1.int main (void)

2.{

3.char c;

4.while((c=getchar())==' ');

5.switch(c)

6. {

7.case'a':

8. printf("a");

9.break;

10.case'q':

11. printf("q");

12.break;

13.default:

14. printf("others");

15.break;

16. }

17.}

我们也可以这样来实现忽略一切空白,当然也可以修改程序使之忽略其他字符。

另外,我们在前文说过,scanf在无法完成彻底模式匹配时,会把剩余的字符放到缓冲区,供下次读取。那么我们来看这样一段代码:

1.int main (void)

2.{

3.int i ;

4.char c;

5. scanf("%d",&i);

6. c=getchar();

7. printf("%c",c);

8.}

由此可知,getchar()也会首先打缓冲区里去读取字符。

1. typedef

在前文中,我们用宏定义来定义了一个BOOL类型,那么现在就用更专业的方式来定义类型。

typedef int Bool;

int main (void)

{

Bool flag=1;

if(flag)

{

printf("True");

}

else

{

printf("false");

}

}

typedef 的作用就是类型定义(Type Definition)。

类型定义有以下三个优点:

1. 易于阅读。比如我们可以把定义一个Dollar,然后Dollar money=1000;这样比用int 来得更容易阅读。

2. 容易修改,如果有一天Dollar要改成double类型,那么我只需要修改类型定义就可以了。

3. 便于移植。在上文中,我们说过C语言是平台相关的,那么我们不妨定义一些Int32,Int64,这样当我们移植时,我们只需要修改这些类型定义就可以了。

那么类型定义较之宏定义有两个优点:

A. 类型定义更为强大,特别是,数组和指针类型是不能定义为宏的。

B. 在作用上,宏定义只是简单的字符串替换,而类型定义却带有一定的封装性。

2. sizeof运算符

这个运算符很简单,就不赘述了,只强调一点。由于sizeof运算符返回的类型时size_t,这是一种自定义的类型,因此,为了防止不同的平台造成的不兼容问题。我们最好在显示前将其进行一次类型转换。

int main (void)

{

printf("%d",(int)sizeof(int));

}

1. 数组大小

我相信,在C#/Java中,更多的人愿意用List来取代数组,一方面是List提供了较多的方法,另一方面也无需我们去指定数组的大小。

那么在C语言中,我们既然需要必须指定数组的大小,而一般来讲,很多数组大小事我们无法确定并且经常会发生变化的,那么我们最好的方式就是用宏定义来限定数组的大小。#define SIZE 10

int main (void)

{

int a[SIZE];

}

如果包含多个数组的话,用宏就很难记忆,那么我们就可以利用sizeof运算符。

int main (void)

{

int a[]={1,3,4,55,6,7,89,9,0};

int i ;

printf("%d",(int)sizeof(a)/(int)sizeof(a[0]));

for(i=0;i<(int)sizeof(a)/(int)sizeof(a[0]);i++)

{

a[i]=0;

}

for(i=0;i<(int)sizeof(a)/(int)sizeof(a[0]);i++)

{

printf("%d\n",a[i]);

}

}

注意,我们之前说过,sizeof返回的值是size_t,因此,我们在计算时,最好将其先强制类型转换为我们可以控制的类型。

2. 数组初始化

一般情况下,我们初始化数组都是把整数数组初始化为0,那么我们一般会怎么做呢?

#define SIZE 5

int main (void)

{

int a[SIZE]={0,0,0,0,0};

}

那么如过SIZE=100怎么办,那么很多人都会这样去做。

#define SIZE 100

int main (void)

{

int a[SIZE];

int i ;

for(i=0;i

{

a[i]=0;

}

}

其实我们完全不用麻烦,这么一句代码就可以搞定了。

#define SIZE 100

int main (void)

{

int a[SIZE]={0};

}

在C99中,提供了一种初始化式,使得我们可以这样来写。

#define SIZE 100

int main (void)

{

int a[SIZE]={[5]=100,[50]=49};

}

而其他的数字就都默认为0。那么我们来考虑这样一段代码:

#define SIZE 10

int main (void)

{

int a[SIZE]={1,2,3,4,5,[0]=6,7,8};

}

那么在C99中,这段代码的结果究竟是什么呢?这个就需要我们来了解一下数组初始化式的原理。

其实,编译器在初始化式数组列表时,都会记录下一个待初始化的元素的位置,比如说在初始化index=0的元素时,会记录下1,这样以此类推,但是当初始化index=5的时候,首

先根据他的初始化式记录下一个待初始化的元素时index=1,然后初始化index=0的元素为6。那么也就是说:最后的结果应该是{6,7,8,4,5,0,0,0,0,0}。

3. 常量数组

当数组加上const就变成了常量数组,常量数组主要有两个好处。

1. 告诉使用者,这个数组是不应该被改变的。

2. 有助于编译器发现错误。

4. C99的变长数组

这是个很爽的东西,我们再也不必担心为数组指定大小而发愁了,指定大了会造成空间的浪费,指定小了又不够用。

在C99中,他的长度会由程序执行时进行计算。

方式如下:

int main (void)

{

int size;

int a[size];

scanf("%d",&size);

}

5. 数组的复制

很多时候,我们需要把一个数组的元素复制到另一个数组上,我们大多数人第一个想到的就是循环复制。

#define SIZE 10

int main (void)

{

int a[SIZE];

int b[SIZE];

int i ;

for(i=0;i

{

a[i]=i;

}

for(i=0;i

{

b[i]=a[i];

}

for(i=0;i

{

printf("%d",b[i]);

}

}

其实还有一种更好的方法是使用memcpy方法,这是一个底层函数,它把内存的字节从一个地方复制到另一个地方,效率更高。

#include

#include

#include

#define SIZE 10

int main (void)

{

int a[SIZE];

int b[SIZE];

int i ;

for(i=0;i

{

a[i]=i;

}

memcpy(b,a,sizeof(a));

for(i=0;i

{

printf("%d",b[i]);

1. 数组作为函数参数

函数是我们学习程序设计语言最基本的东西了,我在此不再赘述。只讨论一种特殊情况,就是数组作为函数的参数传递。

我们都知道,其实在传递数组的时候,实际上是传递了数组首元素的指针。明确了这一点之后,我们就可以思考下面的问题。

既然他只是传递了数组首元素的指针,那么他必然无法知道整个数组的大小,因此,我们如果希望在函数中用到数组的长度,必须要进行显式传递。

int Sum(int a[],int size)

{

int i ,sum=0;

for(i=0;i

{

sum+=a[i];

}

return sum;

}

那么既然,函数无法检测传入数组的长度,我们也可以利用这一个特性来计算数组前N个数的和,或者是利用这一特性来告诉函数,实际上,数组的有效长度要小于数组的真实长度。

2. C99中变长数组作为函数参数

首先在数组一节中,我们谈到了C99中的变长数组是个很好的东西。那么我们来看看变长数组作为函数参数的情况。

我们看之前的代码,size和a[]并没有直接的联系,那么当变长数组作为参数就会解决这样的情况。

int Sum(int size,int a[size])

{

int i ,sum=0;

for(i=0;i

{

sum+=a[i];

}

return sum;

}

这个代码,则明确地表示了数组a的长度是size,也就是说在size和a[]之间建立起了直接的联系。

但是在这里我们需要注意一点,就是参数的顺序,长度一定要写在数组之前,否则会出现a[size]找不到size的错误。

在进行函数声明时,我们可以有以下几种方式:

int Sum(int ,int a[*]);

int Sum(int n ,int a[n]);

int Sum(int n, int a[*]);

int Sum(int ,int a[]);

int Sum(int n ,int a[]);

个人比较推荐第一种,因为我觉得第一种最为简便,而且可以表明a是一个变长数组。像第四种和第五种,我个人认为是两种很不好的方式。

3. C99中数组参数声明使用static

C99中允许在数组参数声明中使用关键字static。例如:

int Sum(int a[static 10],int n)

{

}

从函数本身来讲,static并没有对函数的本身实现造成任何影响。static 10的含义是数组的长度至少是10。那么当函数调用时,编译器会事先从内存中取出10个数,而不是在函数调用的时候才一次次的去取,这样就可以使函数的效率更高。

4. main函数的返回值

在初学C语言的时候,谭老的书上大部分都是这样的代码:

void main ()

{

printf("Hello world");

}

但是实际上,这段函数有两个缺陷:

A. 从编程风格上来看,最好显式地声明main函数没有参数

B. main函数应该返回状态码,在某些操作系统中,程序终止时可以检测到状态码,来监视程序是否正常结束。即使你不需要这个状态码,其他人也可能需要。

因此,这个函数最好这样来实现:

int main (void)

{

printf("Hello world");

return 0;

}

还记得我们之前说过exit(0)么,我们之前说,在main函数中写return 0和exit(0)是没有区别的。那么我们就来看看return 和exit的区别。

exit属于头文件,我们之前说过,0是状态码中成功的意思,那么为了更直观,C标准库为我们提供了这样的两个宏定义。

int main (void)

{

printf("Hello world");

exit(EXIT_SUCCESS); //成é功|

exit(EXIT_FAILURE); //失§败ü

}

让我们转向定义可以发现:

/* Definition of the argument values for the exit() function */

#define EXIT_SUCCESS 0

#define EXIT_FAILURE 1

中的这两个宏定义。但是这两个值并不是固定的,而是由实现定义的。

另外,return 和exit的一个最典型差异就是,在其他函数中调用return 不会引起程序的终止,但是无论在哪里调用exit都会引起程序终止,我们看一个程序。

int main (void)

{

printf("Begin\n");

BreakTest();

printf("End\n");

}

int BreakTest()

{

return 0;

}

这段代码不应该产生任何疑问:

接下来看下这段代码:

int main (void)

{

printf("Begin\n");

BreakTest();

printf("End\n");

}

int BreakTest()

{

exit(EXIT_SUCCESS);

}

由此可知,exit使整个的程序都被终止了。

1. 指针的来源

在当代,大多数的现代计算机都会把内存分割成字节,每个字节都有着其唯一的地址。可执行程序由代码和数据两部分构成,而程序中的每个变量都占有着一个或多个字节,也就是说,每个变量都有着自己的地址。而这个就是指针的来源。

其实每个地址就是一个数,但是我们却不能用数来表示地址,存储地址,我们需要用指针变量。例如int *p = i,我们就可以说p是指针变量,存储着变量i的地址。

那么我们说int *p中,p就是指向int 类型对象的指针变量。

2. 取址运算符和间接寻址运算符

&,取址运算符,如果x是变量,那么&x就是变量x所在的地址。

*,间接寻址运算符,如果p是指针变量,*p就代表p所指向的变量的值。

当我们在程序中声明int *p时,其实并没有让p指向任何地址,只是一个空指针,我们也称之为悬浮指针,在程序中,我们应该尽量避免这样的状况,应该尽量当声明的同时进行初始化。否则当今后不小心对*p进行赋值时,如果p恰好指向了某一块系统内存地址,就会造成系统的崩溃。

其实我们第一次接触取址运算符,应该是应用于scanf,现在我们来想想scanf(“%d”,&a)的含义,其实就是告诉scanf函数,要把读取的值放到哪个地址的下面。

3. const保护参数

我们之前说过const代表常量,不允许改变,那么我们也可以将const应用于指针参数上。例如:

《C语言程序设计》第三章 C语言基础 课堂笔记

页眉内容 《C语言程序设计》第三章C语言基础课堂笔记 §3.1 基本字符集、关键字和标识符 一.基本字符集 字符是C的基本元素,C语言允许使用的基本字符集: 1.26个大写字母A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 2.26个小写子母a b c d e f g h I j k l m n o p q r s t u v w x y z 3.10个阿拉伯数字0 1 2 3 4 5 6 7 8 9 4.其他字符!" # % & ' ( ) * + , - . / : < = > ? [ \ ] ^ _ { | } ~ 5.空格字符以及制表符合换行符等控制字符 二.关键字(P375,附录II) C中具有固定意义的字符串。 (1) C中的关键字共32个,必须用小写字母 (2) 关键字不可用于变量名、函数名等。 auto break case char const continue default do double else enum extern float for goto if int long register return short signed sizeof static struct switch typedef union unsigned void volatile while 三.标识符 标识符用于命名变量、类型、函数和其他各种用户定义的对象,是由字母、下划线和数字三种字符组成。 (1) 第一个字符必须为字母或下划线 (2) C对标识符的长度规定为任意,Turbo C区分32 个字符 (3) C区分大小写 (4) 不允许关键字作为标识符 §3.2 C数据类型

c语言笔记

慕课网C语言第四章笔记 1 多重循环语句的使用: For循环中的变量步进值 2 思维模式的注意一些事项 函数 C语言提供了大量的库函数(右侧资料下载中有),比如stdio.h提供输出函数,但是还是满足不了我们开发中的一些逻辑,所以这个时候需要自己定义函数,自定义函数的一般形式:

注意: 1、[]包含的内容可以省略,数据类型说明省略,默认是int类型函数;参数省略表示该函数是无参函数,参数不省略表示该函数是有参函数; 2、函数名称遵循标识符命名规范; 3、自定义函数尽量放在main函数之前,如果要放在main函数后面的话,需要在main函数之前先声明自定义函数,声明格式为:[数据类型说明] 函数名称([参数]); 那么函数的返回值是指函数被调用之后,执行函数体中的程序段所取得的并返回给主调函数的值。 函数的返回值要注意以下几点: 1. 函数的值只能通过return语句返回主调函数。return语句的一般形式为: return 表达式或者为:return (表达式); 2. 函数值的类型和函数定义中函数的类型应保持一致。如果两者不一致,则以函数返回类型为准,自动进行类型转换。 3. 没有返回值的函数,返回类型为void。如果小刚算了一会没有返回结果的话,那么用代码表示就是: 注意:void函数中可以有执行代码块,但是不能有返回值,另void函数中如果有return语句,该语句只能起到结束函数运行的功能。其格式为:return; 错误!

错误! 函数的调用的一些问题 #include /* Jone算出结果应该怎么写函数? */ int joneResult(int x, int y, int z) { int sum = x+y+z; return sum/3; //这里是不是应该将sum返回呢? } /* Jack没有算出结果只说了一句话是不是应该用无返回值函数? */ void jackResult(int x, int y, int z) { printf("我算不出来\n"); return 0; } int main() { int a, b, c; a = 10; b = 20; c = 30; //Jone的返回值类型是什么? int jR = joneResult(a, b, c);

C语言笔记_me

预编译处理: 1.宏定义 形式:#define 标识符字符串 说明: 宏名一般用大写。 宏定义不作语法检查,只有在编译被宏展开后的源程序时才会报错。 宏定义不是C语句,不在行末加分号。 宏名有效范围为定义到本源文件结束。 可以用#undef命令终止定义的作用域。 在宏定义时,可以引用已定义的宏名 带参数的宏定义 形式:#define 宏名(参数表)字符串 2.文件包含处理 #include “文件1” 就是交文件1的全部内容复制插入到# include位置,作为一个源文件进行编译。 3.条件编译 条件编译:指不对整个程序都编译,而是编译满足条件的那部分。有以下几种形式: ①.# ifdef 标识符 程序段1 #else 程序段2 #endif 作用:当标识符在前面已经被定义过(一般用#define),则对程序段1编译,否则 对程序段2编译。 ②.# if 标识符 程序段1 #else 程序段2 #endif 作用:和# ifdef相反,当标识符没被定义过时,才对程序段1编译。 ③.# ifndef 表达式 程序段1 #else

程序段2 #endif 作用:当表达式值为真(非0)时,对程序段1编译,否则对程序段2编译。 条件编译的应用 全局变量应该是得到内存分配且可以被其他模块通过C语言中extern关键字调用的变量。因此,必须在.C 和.H 文件中定义。这种重复的定义很容易导致错误。 以下讨论只需用在一个头文件中定义一次, 1.首先,说明一个条件编译命令: #ifdef 标识符 程序1 #else 程序2 #endif 先在一个头文件(.h)中输入条件编译命令。 那么,对C程序(.c)进行编译时,若程序包令: #include标识符 或#include标识符0 即:只要有标识符出现,编译时就会加入程序1,一并进入编译。否则,加入程序2。 例:在uCOS_II.H 中包含: #ifdef OS_GLOBALS #define OS_EXT #else #define OS_EXT extern #endif OS_EXT INT32U OSIdleCtr; OS_EXT INT32U OSIdleCtrRun; OS_EXT INT32U OSIdleCtrMax; 同时,uCOS_II.C中包含: #define OS_GLOBALS (当然,所有.C应该都包含#include uCOS_II.H,这样才达到.C文件能访问全局 变量) 这样,当编译器处理uCOS_II.C时,它使得头文件变成如下所示,因为OS_EXT被设置为空。编译器就全局变量分配在内存,而当编译其他不含#define OS_GLOBALS的.C文件时,OS_EXT被设置为extern,表示该变量为外部定义的全局变量,不用再分配内存了。 其实,这样是将一个C文件的所有全局变量定义在一个头文件中,而所有C文件都包含这个头文件,这样防止重复定义一个全局变量而发生错误。

郝斌老师C语言笔记

专题: 动态内存分配(所有高级语言,没有C里深刻) 传统数组的缺点: 1.数组长度必须事先指定,而且只能是常整数,不能是变量 例子int a[5];//必须事先指定,而且只能是常整数 int len = 5; int a[len];//error 2.传统形式定义的数组,该数组的内存程序员无法手动释放 数组一旦定义,系统为数组分配的内存空间就会一直存在,除非数组所在的函数运行终止。 在一个函数运行期间,系统为该函数中的数组分配的空间会一直存在。 直到该函数运行完毕时,数组的空间才会被系统自动释放。 例子:void f(void){int a[5]={1,2,3,4,5};....} //数组a 占20个字节的内存空间,程序员无法手动编程释放它,数组a只能在f()函数结束被系统释放 3. 数组的长度一旦定义,数组长度就不能再更改。 数组的长度不能在函数运行的过程中动态的扩充或缩小 4. 传统方式定义的数组不能跨函数使用 A函数定义的数组,只有在A函数运行期间才可以被其他函数使用, 但A函数运行完毕后,A函数中的数组将无法在被其他函数使用。 #include void g(int * pArr, int len) { pArr[2] = 88; //parr[2]==a[2] 等价于 } void f(void) { int a[5] = {1,2,3,4,5}; //数组a 只在f()执行时有效 g(a,5); printf("%d\n", a[2]); } int main(void) { f(); // 结果: 88 //printf("a[0] = %d\n", a[0]); // error return 0; } 为什么需要动态分配内存 很好的解决的了传统数组的4个缺陷 动态内存分配举例_动态数组的构造难点

郝斌C语言详细笔记(附源码)

郝斌老师的C语言:课堂讲解全程动手敲代码,讲解细致,对于重要知识点的讲解不厌其烦,是一个难得的C语言入门教程。在这里对老师的辛勤付出表示感谢。 郝斌c语言视频教程 · 概述: 课程计划 为什么学习c语言: Fortran语言主要用于科学计算,在第三代语言中,以1980年为分水岭,分为结构化和面向对象语言。Basic语言是vb的前生,pascal语言一般是用于教学。C语言是最重要的,其他的语言一般很少用了。结构化的代表语言是c语言。结构化语言的数据和操作是分离的,导致在写大项目的时候,会出现各种各样莫名其妙的问题。 在面向对象的语言中c++是最复杂的语言。由于c++语言太复杂,sun公司对c++进行了改装,产生了java语

言。而c#是由微软开发的,和java相似,几乎一模一样。 在高级语言的执行速度上,c是最快的,c++其次,而java 和c#是最后的。Java和c#流行,主要的一个原因是可以跨平台。 C语言的发展和过程:

C语言的特点: ·优点:代码量小,速度快,功能强大。 ·缺点:危险性高,开发周期长,可移植性弱。 危险性高:写同一个程序,在java中会报错,而在c中不会报错,为什么呢,因为c认为程序你想怎么写就怎么写,c语言认为你写的程序不是很离谱,他都认为你写的这个程序有特殊的含义。可以直接通过,而java 则不可以。 开发周期长:c语言是面向过程的语言,面向过程的语言的特点就是在开发大项目的时候,很容易崩溃,好比盖大楼,C语言还要造大量的砖块、钢筋等结构原材料,而C++ C# JAVA则进行了一定的继承封装等操作,相当于原材料直接给你,你只需要用它盖楼即可。 现在市场上的语言分三块

c语言学习笔记(数组、函数)

数组 2010-3-29 22:40 一维数组的定义和一维数组的引用 内存中一串连续的存储单元(变量),叫数组。指针移动和比较只有在一串连续的数组中才有意义。 当数组中每个变量只带一个下标时,为一维数组。 定义一个一维数组: 类型名数组名【常量表达式】如:int a[8]; 说明:①定义一个一维整型名为a的数组。 ②方括号中规定此数组有8个元素,(a【0】-a【7】),不存在a【8】这个元素。 ③a数组中每个元素均为整型,且每个元素只能存放整型。 ④每个元素只有一个下标,且第一个元素的下标总为0。 ⑤c编译程序,为a数组开辟8个连续存储单元。 3)在定义数组语句中,可以有多个数组说明符;它们用逗号隔开。 例:double a【22】,v【100】,u【5】,a,b,c;注:双精度型每个单元占用8个字节的存储空间。另外,也可以和普通变量一起定义。 用逗号分隔开。 2010-3-23 10:29 一维数组元素的引用2 1) 引用形式:数组名【下标表达式】可以是:常量,变量,表达式。 如:double x【8】则x【0】x【j】x【i+k】均合法 2) (1)一个数组元素实际上就是一个变量名,代表内存中的一个存储单元。我们可以把数组元素看做一个变量名来处理。 (2)一个数组不能整体引用,数组名中存放的是一个地址常量,它代表整个数组的首地址。当学习指针时,引用的变量的地址,就是变量中第一个字节的地址。数组的首地址也是它的第一个元素的第一个字节的地址,即它的首地址。 数组的首地址存放在数组名中。所以说,数组名就代表一个地址。数组名是一个地址值。 (3)在引用数组元素时,数组元素下标表达式必须是整数,下标表达式下限为0.系统并不自动检验数组元素下标是否越界,因此编程时要注意。 如:double a,b; int c[10]; a=2.0;b=3.0; 则a[i]; 是不合法的。 给数组赋初值时,如果所赋初值少于元素个数时,后面的元素补为0,字符补为’\0’可以通过赋初值来定义一个数组的大小。如:int a[]={0,0,0,0,0}; 相当于:a[5]={0};

c语言读书笔记

Vc++读后感 闲来无事,跑来图书馆,突然被一本名叫《致程序员之家论坛的所有会员》的书把我的注意力吸引过去了,于是我用心的读起来了。下面这些是我做的一些笔记。 应该掌握程序运行的原理与机制:学习VC++6.0 在WINDOWS下编程,就应该了解WINDOWS消息机制。(关于消息机制不用太深入,新手学习一个大概流程就可以了) 掌握编程的思想:这点就比较难了,C++的编程就是面向对象,对象的概念一定要清楚。这点重要是多练习自己动手做做小程序。 多动脑,多动手,再加上十分的仔细:关于这点就是一个学习态度的问题了。勤劳和懒惰都是人天生都有的本性,就看我们选择那一个了。 在编写一个程序的时候,要知道为什么要去编它,在程序中的函数为什么这么调用,这个程序的内存模型是怎样的?可以这样说:我们做任何事前都要有目标,有目标才能前进,函数流程就是一个程序的生命,就像人们血液流动的过程一样,从心脏出发经过各个脏器,我们要了解的就是经过那一些,那一些是主要的脏器,这些脏器是用来干什么的。最终回到那里去。内存模型蛮专业化的词,不过不用怕,就是数据在内存客中排列的顺序结构,谁在前面谁在后面了解就可以了。 程序语言的学习,是一个循序渐进的过程,切忌急功近利 这一点我认为最重要,我们往往想静心学习一点东西都不是很容易,总是想一口气吃成个大胖子,这种心态,去学习任何事情都不会成功的,笔者自己也是一样,经常想马上就学会,最后是什么也学不会。只能一步一步来,天才少,努力的人才多。切忌急功近利。 我们往往会因为不知从何入手而不知不觉中走了弯路,停留于表面,你越是着急,反而越容易走弯路,越是搞不懂,就越是需要我们的耐心,不过我也知道这个说说容易做做难,我的方法是,烦的时候回到原点想想你为什么学习编程,也许会对你好一点。每一个人的情况不同,所以要找对自己最有效果的。

(考研复试)C语言笔记资料

(考研复试)C语言笔 记

1:用高级语言编写的程序叫做源程序,然后用编译程序吧源程序翻译成二进制的目标程序,然后将该目标程序与系统函数库以及其他目标程序连接,形成可执行程序。 2:算法五个特点:确定性,有穷性,输入,输出,可行性。 3:程序流程图、N-S盒图、伪代码 4:int 无论有符号无符号,都是16位 Short 无论是有符号还是无符号都是16位 Long 无论是有符号还是无符号都是32位 Float 32位 double 64位,long double 128位。 一个整型常量后面加u就是无符号,加l就是长整型5:\t,\b退格,\r移到本行开头 6:‘0’48,‘A’65,‘a’97,差值32 7:级别char

13:整形给long,同char给int一样, 14:putchar() Getchar() Puts(),gets() Printf(“%md”,d) %d,%c,%f,%ld,%o,%x,%u,%s %d的原意是,按十进制整形数据输出 M表示输出字段的宽度,数字靠右拜访。如果数字太大,就输出数字,不管m. Printf(“%m.ns”,d) 输出占m列,靠右端,只取字符串中的前n个字符,如果n大于m,则不管m Printf(“%-m.ns”,d) 输出占m列,靠左端 Printf(“%m.nf”,d) %f输出实数,包括单精度和双精度,只能输出六位小数, 输出n位小数 Printf(“%m.ne”,d) N指的是输出小数的位数, Scanf输入整形,分割可以用回车或者tab或者空格但是不能用逗号 Scanf(“%3d%3d”,&a,&b)输入123456.

c语言学习笔记

网络通讯中数据大小端的问题: 大端模式:高位字节放在内存的低地址端,即该值的起始地址;低位字节排放在内存的高地址端。 小端模式:低位字节放在内存的低地址端,即该值的起始地址;高位字节放在内存的高地址端。 数组的名字是一个常量指针,如X【2】,X是一个常量指针,没有分配的内存。 数据存在存储空间,数值不存在。 在C语言里,指针可以访问到任何地方,但是对不应该访问的地址进行访问没有意义,也可能会禁止读写。 函数的接口类型,可变参数的类型和执行跳转: C语言的函数名可以看做一个地址常量(和数组一样)。 系统的堆栈:堆和栈的第一个区别就是申请方式不同:栈(英文名称是stack)是系统自动分配空间的,例如我们定义一个char a;系统会自动在栈上为其开辟空间。而堆(英文名称是heap)则是程序员根据需要自己申请的空间,例如malloc(10);开辟十个字节的空间。由于栈上的空间是自动分配自动回收的,所以栈上的数据的生存周期只是在函数的运行过程中,运行后就释放掉,不可以再访问。而堆上的数据只要程序员不释放空间,就一直可以访问到,不过缺点是一旦忘记释放会造成内存泄露。、 、 预处理操作: 宏定义:#define M 3; #define M(x,y) 2*x+y; 预处理对宏的处理,分为3类: 预处理“标识符”的展开; 预处理“标识符”的判断; 预处理“标识符”的文本替换。 #if 0 。。。。 #endif 用作代码注释。 基础类型重定义:一个C程序在PC上开发,逻辑验证正确后,下需要移植到某个嵌入式系统中,但是它们对应的int的位宽定义不同,目标系统是X86时,编译器将其看做32位,而目标系统为嵌入式系统的时候,编译器将其看作16位(对应的32位为long关键词)。这种情况,就需要进行基础类型的重定义: #define _TARGET_X86_SYSYTEM 0 #define _TARGET_DEV_SYSYTEM 1 #define _TARGET_SYSYTEM _TARGET_X86_SYSYTEM #if(_TARGET_SYSYTEM = _TARGET_X86_SYSYTEM) Typedef signed int _i32 Typedef unsigned int _u32 #elif(_TARGET_SYSYTEM = _TARGET_DEV_SYSYTEM)

最新(考研复试)C语言笔记

1:用高级语言编写的程序叫做源程序,然后用编译程序吧源程序翻译成二进制的目标程序,然后将该目标程序与系统函数库以及其他目标程序连接,形成可执行程序。 2:算法五个特点:确定性,有穷性,输入,输出,可行性。3:程序流程图、N-S盒图、伪代码 4:int 无论有符号无符号,都是16位 Short 无论是有符号还是无符号都是16位 Long 无论是有符号还是无符号都是32位 Float 32位 double 64位,long double 128位。 一个整型常量后面加u就是无符号,加l就是长整型 5:\t,\b退格,\r移到本行开头 6:‘0’48,‘A’65,‘a’97,差值32 7:级别char

14:putchar() Getchar() Puts(),gets() Printf(“%md”,d) %d,%c,%f,%ld,%o,%x,%u,%s %d的原意是,按十进制整形数据输出 M表示输出字段的宽度,数字靠右拜访。如果数字太大,就输出数字,不管m. Printf(“%m.ns”,d) 输出占m列,靠右端,只取字符串中的前n个字符,如果n大于m,则不管m Printf(“%-m.ns”,d) 输出占m列,靠左端 Printf(“%m.nf”,d) %f输出实数,包括单精度和双精度,只能输出六位小数, 输出n位小数 Printf(“%m.ne”,d) N指的是输出小数的位数, Scanf输入整形,分割可以用回车或者tab或者空格但是不能用逗号 Scanf(“%3d%3d”,&a,&b)输入123456. 系统自动把123赋值给a,456赋值给b;同理,如果系统输入abc三个字符,但是ch只能容纳一个,就吧a给ch,bc给后面的。

大学C语言笔记

第一章概述 1. C语言的特点 ①语言简洁、紧凑,使用方便、灵活。共有32个关键字,9种控制语句。 ②运算符丰富,公有34种运算符。 ③数据结构丰富,数据类型有:整型、实型、字符型、数组、指针、结构体、共用体等。 ④具有结构化的控制语句(如if…else、while、do…while、switch、for) ⑤语法限制不太严格,程序设计自由度大。 ⑥允许直接访问物理地址,能进行位(bit)操作,可以直接对硬件操作。 ⑦生成目标代码质量高,程序执行效率高。 ⑧可移植性好。 2. C语言的用途 C虽不擅长科学计算和管理领域,但对操作系统和系统实用程序以及对硬件进行操作方面,C有明显的优势。现在很多大型应用软件也用C编写。 Top of Page 第二章数据类型、运算符与表达式 1. C的数据类型 C的数据类型包括:整型、字符型、实型或浮点型(单精度和双精度)、枚举类型、数组类型、结构体类型、共用体类型、指针类型和空类型。 2.常量与变量 常量其值不可改变,符号常量名通常用大写。变量其值可以改变,变量名只能由字母、数字和下划线组成,且第一个字符必须为字母或下划线。否则为不合法的变量名。变量在编译时为其分配相应存储单元。 3.整型数据 整型常量的表示方法:十进制不用说了,八进制以0开头,如0123,十六进制以0x开头,如0x1e。 整型变量分为:基本型(int)、短整型(short int)、长整型(long int)和无符号型。不同机器上各类数据所占内存字节数不同,一般int型为2个字节,long型为4个字节。 4.实型数据 实型常量表示形式:十进制形式由数字和小数点组成(必须有小数点),如:0.12、.123、123 0.0等。指数形式如123e3代表123×10的三次方。 实型变量分为单精度(float)和双精度(double)两类。在一般系统中float型占4字节,7位有效数字,double型占8字节,15~16位有效数字。 5.字符型数据 字符变量用单引号括起来,如'a','b'等。还有一些是特殊的字符常量,如'\n','\t'等。分别代表换行和横向跳格。 字符变量以char 来定义,一个变量只能存放一个字符常量。 字符串常量是由双引号括起来的字符序列。这里一定要注意'a'和"a"的不同,前者为字符常量,后者为字符串常量,c规定:每个字符串的结尾加一个结束标志'',实际上"a"包含两个字符:'a'和''。 6.数值型数据间的混合运算 整型、字符型、实型数据间可以混合运算,运算时不同类型数据要转换成同一类型再运算,转换规则: char,short -> int -> unsigned -> long -> double <- float 7.运算符和表达式 c运算符包括: 算数运算符(+ - * / % ) 关系运算符( > < == >= <= != ) 逻辑运算符( ! && || ) 位运算符( << >> ~ | ^ & ) 赋值运算符(= ) 条件运算符(? : ) 逗号运算符( , ) 指针运算符( * & )

C语言学习资料经典笔记

下载大学学习资料就到学姐学长网全部资料免费https://www.360docs.net/doc/d414425820.html, C语言学习资料经典笔记 目录 第一章C语言概述 (1) 第二章算法 (1) 第三章数据类型、运算符与表达式 (2) 第四章顺序结构程序设计 (6) 第五章选择结构程序设计 (8) 第六章循环控制 (9) 第七章数组 (10) 第八章函数 (11) 第九章预处理命令 (13) 第十章指针 (13) 第一章C语言概述 1、C程序的组成和形式的基本特点(P6-7) (1)C程序是由函数构成的,一个C main函数,也可以包含一个main函数和若干个其他函数。 (2)一个函数由两部分组成 a) 函数的首部:即函数的第一行,包括函数名、函数类型、函数属性、函数参 数名、参数类型 例:int max (int x,int y) 一个函数名后面必须跟一对圆括号,括号内写函数的参数名及其类型。函数可以没有参数,如main()。 b) 函数体:即函数首部下面的花括号内的部分。如果一个函数内有多个花括号, 则最外层的一对花括号为函数体的范围。函数体一般包括:声明部分、执行部分 2、运行C程序的步骤及每个步骤生成文件的类型及特点(P7) 第二章算法 1、算法的定义 一个程序应包括①数据结构即对数据的描述;②算法也就是操作步骤。 计算机算法可分为两大类:数值运算算法和非数值运算算法。 2、算法的特性(P19) 1. 有穷性;

2. 确定性; 3. 有零个或多个输入; 4. 有一个或多个输出; 5. 有效性。 3、描述算法的常用方法(P20-33) 2.自然语言; 3.用流程图表示算法。 4.N—S图 5.计算机语言 6.伪代码 4、C程序算法的3种基本结构及其共同特点(P24-25)三种基本结构: a) 顺序结构:最基本; b) 选择结构:又称选取结构或分支结构; c) 循环结构:又称重复结构; a) 当(while)型循环; b) 直到(until)型循环。 共同特点: 1. 只有一个入口; 2. 只有一个出口; 3. 结构内的每一部分都有机会被执行到; 4. 结构内不存在“死循环” 。 5、结构化程序设计的设计原则(P34) a) 自顶向下; b) 逐步细化; c) 模块化设计; d) 结构化编码。 第三章数据类型、运算符与表达式 1 、C语言的基本数据类型和构造数据类型(P37)

C语言基础学习笔记

C语言基础学习笔记 (第一版修改) 丁炳亮 1数据类型和表达式 1.1计算机内数据存储方式 理解与测试: 什么是补码?我们得先知道模的概念。模“模”是指一个计量系统的计数范围。如时钟等。计算机也可以看成一个计量机器,它也有一个计量范围,即都存在一个“模”。例如:时钟的计量范围是0~11,模=12。表示n位的计算机计量范围是0~2^(n)-1,模=2^(n)。 “模”实质上是计量器产生“溢出”的量,它的值在计量器上表示不出来,计量器上只能表示出模的余数。任何有模的计量器,均可化减法为加法运算。例如:假设当前时针指向10点,而准确时间是6点,调整时间可有以下两种拨法:一种是倒拨4小时,即:10-4=6;另一种是顺拨8小时:10+8=12+6=6在以12模的系统中,加8和减4效果是一样的,因此凡是减4运算,都可以用加8来代替。对“模”而言,8和4互为补数。实际上以12模的系统中,11和1,10和2,9和3,7和5,6和6都有这个特性。共同的特点是两者相加等于模。 二进制中整数的补码求法是:正数的补码为原码,负数的补码是符号位不变其他位全部取反再整个数加1。我们可以通过下面的代码看下负整数在计算机内部的表示。 void f(int n) { unsigned int i; for(i=1,i<<=15;i;i>>=1) { if(i&n) printf("1"); else printf("0"); } printf("\n"); } main() { int a=-0xff; f(a);

} 输出的结果是1111111100000001。 1.2变量与常量 理解与测试: 1)类型声明 在计算机内部数据是以字节为单位存储的,但是我们需要的数据类型有很多种,每种数据类型所占字节和存储方式都不一样。类型声明的作用就是告诉计算机以哪种“格式”去读写该数据数据。 类型说明符变量名1,变量名2......,变量名n; 类型说明符有基本类型(字符型、整数型、单/双精度型)、高级类型(结构体型、共用体型、枚举类型)、指针型等,其中指针类型包括指向基本类型的指针类型、指向高级类型的指针型和指向函数的指针类型(指向函数指针声明格式在后面章节)。 2)符号常量的定义 #define 标识符常量; 使用该种方法定义符号常量一个是可以使代码便于阅读理解,另一个是方便代码内部多个相同常量的统一修改。 总结与注意 在写计算式的时候要考虑变量是否会越界。一般来说计算式子时是先强制转换成式子中最大存储空间的数据类型(不包括被赋值的变量),还要注意不同的类型数据在不同的编译器中所占的内存有可能是不一样的,例如有些编译器整型是占2个字节有些是占4个字节。同时还要考虑到符号的优先级和结合顺序,如果按符号的优先级和结合顺序运算过程中有越界的那么整个计算结果可能和预想的不一样了,例如int i=100;i = 500*i/i;最后i=-155。 1.3输出输入 理解与测试: 1)格式化输入输出函数可以按设定的格式和设定的数据类型接收和输出多个变量。控制格式和数据类型的是数据控制符。 2)字符和字符串可以用专门的输出\输入函数。主要有getch(); putch();getchar(); putchar(); gets(); puts();其中getch()和putch()是conio.h中声明,getch()不需要等待回车键就返回字符并立即执行下面一语句符,getch()不在屏幕显示输入的字符。getchar();putchar(); 在stdio.h中声明。getchar()读取键盘上的一个字符,立即返回并显示在屏幕上,需要等待回车键才能执行下

C语言程序设计谭浩强重点笔记

C语言设计 学习笔记 早晨:06:40 起床 07:20——08:20 英语 1小时 新概念英语(单词、语法、听读背) 大学英语(单词、语法、听读背) 上午:08:30——10:30 计算机基础 2小时 10:50——11:30 计算机科学技术导论 计算机组成原理 微机原理及接口技术 Intel微处理器结构编程与接口 深入理解计算机系统 80x86汇编语言程序设计 8086-8088宏汇编语言程序设计教程 BIOS研发技术剖析 自己动手写操作系统 操作系统原理 Windows操作系统原理 Windows内部原理系列 Windows程序内部运行原理 计算机网络第五版 中午:12:00——02:00 午休 下午:02:30——04:30 计算机应用及编程 Windows用户管理指南、AD配置指南、网络专业 指南、Windows即学即会教程 Windows下32位汇编语言程序设计、C#编程 晚上:05:30——08:00 锻炼、晚餐 08:00——09:00 辅导 09:00——11:00 专业基础 2小时 大学数学、大学物理、电机及拖动、电力电子技 术、通信技术 11:30 休息

目录 第一章C语言概述................................................................................................................................. - 1 - 1.1 C程序结构特点16 ................................................................................................................ - 1 - 1.2 C程序上机步骤17 ................................................................................................................... - 1 -第二章程序的灵魂——算法23 ............................................................................................................ - 2 - 2.1 算法24 ..................................................................................................................................... - 2 - 2.2 算法的三种基本结构............................................................................................................... - 2 - 2.3 结构化程序设计方法42 .......................................................................................................... - 2 -第三章数据类型运算符与表达式48 .................................................................................................. - 2 - 3.1 C语言的基本元素48 ............................................................................................................... - 2 - 3.2 C的数据类型48 ....................................................................................................................... - 2 - 3.3 常量与变量48 .......................................................................................................................... - 3 - 3.4 基本类型................................................................................................................................... - 3 - 3.5 变量63 ..................................................................................................................................... - 4 - 3.6 不同类型数据间的混合运算................................................................................................... - 5 - 3.7 函数的调用过程(补充)....................................................................................................... - 5 -第四章最简单的C程序设计——顺序程序设计77 ........................................................................... - 5 - 4.1 字符数据的输入输出............................................................................................................... - 5 -第五章选择结构的程序设计97 ............................................................................................................ - 6 -第六章循环结构程序设计..................................................................................................................... - 6 - 6.1 语句标号................................................................................................................................... - 6 - 6.2 break语句和continue语句 ...................................................................................................... - 6 -第七章数组132 ...................................................................................................................................... - 6 - 7.1 构造类型................................................................................................................................... - 6 - 7.2 数组133 ................................................................................................................................... - 6 - 7.3 二维数组................................................................................................................................... - 7 - 7.4 字符串——字符数组............................................................................................................... - 7 - 7.5 字符串处理函数#include ...................................................................................... - 7 -第八章函数153 ...................................................................................................................................... - 8 - 8.1 c程序的结构154 ...................................................................................................................... - 8 - 8.2 函数调用参数传递................................................................................................................... - 8 - 8.3 函数变量的作用范围............................................................................................................... - 8 - 8.4 变量的存储类别....................................................................................................................... - 9 -第九章预处理命令197 ........................................................................................................................ - 10 - 9.1 预编译命令作用..................................................................................................................... - 10 -第十章指针211 .................................................................................................................................... - 11 - 10.1 变量的访问方式................................................................................................................... - 11 - 10.2 指针变量............................................................................................................................... - 11 -第十一章结构体270 ............................................................................................................................ - 12 - 11.1 结构体270 ............................................................................................................................ - 12 -

相关主题
相关文档
最新文档