C语言容易忽略的问题

目录

1  取模符号+自增问题

2  ~scanf问题

3  if else问题

4 Switch case 问题

5  if返回值问题

6  浮点数精度问题

7  变量初始化问题

8  指针部分

9  结构体

10  文件

10.1  函数

 10.2  示例

11  static extern

12  二进制运算

12.1  逻辑运算符

12.2  位移运算(左移/右移)

13  基本概念


1  取模符号+自增问题

我们不妨尝试写这样的程序

#include<stdio.h>
int main()

{
	int n,t=5;
	printf("%d\n",7%(-3));//1
	printf("%d\n",(-7)%3);//-1
	while(--t)
	printf("%d\n",t);
	t=5;
	while(t--)
	printf("%d\n",t);
	return 0;
}

运行结果如下:

 第一个运行结果为1, 第二个运行结果为-1,说明取模运算的符号取决于被除数

i++代表先判断之后再+1,++i代表+1之后再进行判断

所以第一个循环打印到1就结束了,第二个循环还能够打印0

例题1:

 首先明确:y--这种自减是先判断表达式是否成立之后再-1

推导过程:

1.y=2进入循环,判断while循环条件成立(2!=-1),然后y=2-1=1,进入dowhile循环,a=1*1=1,a=1+1=2,判断dowhile循环条件成立(1!=0),然后y=1-1=0,进入下一次循环

2.y=0,a=3进入循环,判断while循环条件成立(0!=-1),进入dowhile循环,a=1*0=0,a=0+1=1,判断dowhile循环条件不成立(0!=0),跳出dowhile循环

3.y=-1,判断while循环条件不成立(-1!=-1),结束while循环

我的测试:

#include <bits/stdc++.h>
using namespace std;

int main()
{
	int y,a;
	y=2;
	a=1;
	while(y--!=-1)
	{
		cout<<"y="<<y<<endl;
		do
		{
			a*=y;
			cout<<"a="<<a<<endl;
			a++;
			cout<<"a="<<a<<endl;
		}while(y--);
		cout<<"y="<<y<<endl;
	}
	printf("%d,%d",a,y);
	return 0;
}

可以对照着输出值来理解 

例题2:

简单来说,a[1]和a[4]进行了一次交换,a[2]和a[3]进行了两次交换(等价于没交换)

2  ~scanf问题

~是按位取反

scanf的返回值是输入值的个数

如果没有输入值就是返回-1

-1按位取反结果是0

while(~scanf("%d", &n))就是当输入EOF的时候退出循环

3  if else问题

不要因为格式的问题而被误导!!

没有括号说明else和上一行的if是紧紧关联的 

所以,当x>0时,y=1;当x<0时,y=0;当x=0时,y=-1

 当x>0时,y=1;当x=0时,y=-1;当x<0时,y=0

例:

ABDif内包含3条语句,C只能 包含一条语句

4 Switch case 问题

用一道例题解释如何解决case后面不能跟范围的问题:

输入分数(百分制),对应分数段输出等级,85分以上输出A,70-84分输出B,60-69分输出C,剩下输出D,要求运用Switch case语句

问题1:如何避免范围问题

解答1:可以把分数转换成10分制,10分对应100分,9分对应90-99分,8分对应80-89分。。。。。。

问题2:如何解决85分为边界的问题

解答2:可以把85-89之间的分数在转换成10分制前提高5分,这样85-89之间的数字变成90-94分就好处理了

代码:

#include <stdio.h>
int main()
{
	int score;
	scanf("%d",&score);
	if(score<0||score>100)
	{
		printf("enter data error");
	}
	else
	{
		if(score>=85&&score<=100)
		{
			score+=5;
		}
		int score2=score/10;
		switch(score2)
		{
			case 10://printf("A"); break;
			case 9:printf("A"); break;
			case 8://printf("B"); break;
			case 7:printf("B"); break;
			case 6:printf("C"); break;
			default:printf("D"); break;
		}
	}
	return 0;
 } 

5  if返回值问题

如果为真,则返回1

如果为假,则返回0 

例1:

5>3 为真,所以返回1

1>1 为假,所以返回0

所以if条件不成立,执行else

例2:

 y先被赋值为50,然后再和z比较,发现成立,所以执行if语句

例3:

 x=10已经成立,不需要看后面的语句,所以y不被重新赋值,所以执行if语句

6  浮点数精度问题

#include <stdio.h>
#include <math.h>
int main()
{
	double a,b,c,delta,x1,x2,realpart,imagpart;
	scanf("%lf%lf%lf",&a,&b,&c);
	printf("The equation:");
	if(fabs(a)<=1e-6) printf("is not a quadratic\n");
	else
	{
		delta=b*b-4*a*c;
		if(fabs(delta)<=1e-6) printf("has two equal roots:%8.4f\n",-b/(2*a));
		else 
		{
			if(delta>1e-6)
			{
				x1=-b+sqrt(delta)/(2*a);
				x2=-b-sqrt(delta)/(2*a);
				printf("has distinct real roots:%8.4f and %8.4f\n",x1,x2);
			}
			else
			{
				realpart=-b/(2*a);
				imagpart=sqrt(-delta)/(2*a);
				printf("has complex roots:\n");
				printf("%8.4f+%8.4fi\n",realpart,imagpart);
				printf("%8.4f-%8.4fi\n",realpart,imagpart);
			}
		}
	}
	return 0;
}

7  变量初始化问题

例题1:

最终输出a[2],a[2]初始化为0,所以输出0

例题2:

s[1]没有初始化,不能确定k的值

强调:不同的编译器对于未初始化的值的默认赋值情况有差异,建议在初始化时不要偷懒

8  指针部分

例题1:

利用指针,设计函数fun(),功能是:将键盘输入进s所指字符串中ASCⅡ值为偶数的字符删除,串中剩余字符形成一个新串放在t所指的数组中,并输出。

例如,若s所指字符串中的内容为AB2,其中字符B的ASCⅡ码值为偶数、字符2的ASCⅡ码值为偶数,都应当删除,其他依次类推。最后输出t所指的数组中的内容应是A。s的输入和t的输出均不加任何修饰符号。scanf("%s",s);printf("%s", t);

方法1:数组

#include <stdio.h>
char *s,*t;
char s1[100],t1[100];
int cnt=0;
char* fun(char* s,char* t)
{
	for(int i=0;*(s+i)!='\0';i++)
	{
		if(*(s+i)%2!=0)
		{
			*(t+cnt)=*(s+i);
			cnt++;
		}
	}
	*(t+cnt)='\0';//结束标志 
	return t;
}
int main()
{
	s=s1;
	t=t1;
	scanf("%s",s);
	printf("%s",fun(s,t));
	return 0;
} 

方法2:malloc

#include <stdio.h>
#include <malloc.h>
char *s,*t;
int cnt=0;
char* fun(char* s,char* t)
{
	for(int i=0;*(s+i)!='\0';i++)
	{
		if(*(s+i)%2!=0)
		{
			*(t+cnt)=*(s+i);
			cnt++;
		}
	}
	*(t+cnt)='\0';//结束标志 
	return t;
}
int main()
{
	s=(char*)malloc(sizeof(char)*100);
	t=(char*)malloc(sizeof(char)*100);
	scanf("%s",s);
	printf("%s",fun(s,t));
	free(s);
	return 0;
} 

注意:如果这两个程序不写字符串结束标志,那么可能会接一串乱码

例题2:

 AB好判断,主要在C选项上

对于一个指针变量,我们在向指针变量存储值时一定要注意是否已经明确指针指向了哪块空间

对于C来说就是这个问题,在scanf之前并没有给指针开辟某一块空间(野指针),所以没法存储数据,所以C错误

所以D正确

例题3:

 如果把最后一行*to='\0'去掉,由于a要复制到b,而且b的长度大于a的长度,那么a会覆盖一部分的b然后接上没有被a覆盖部分的b

如果改变a和b,使得b的长度小于a的长度,那么会直接报错(b的空间不够了) 

9  结构体

例题1:结构组成

struct 结构体名 结构体变量名;

struct Student stu1;    //定义结构体变量

这里,struct是结构体类型的关键字

example是结构体变量名

x,y,z是结构体类型名

struct ex是结构体类型

ex是结构体类型名 

例题2:(其实不算结构体的问题,只是拿这个举个例子)

有如下程序:

#include <stdio.h>

int main()
{
	struct s{
		char num1[100];
		char num2;
		char num3[100];
		char num4[100];
	}s1;
	scanf("%s%c%s%s",s1.num1,&s1.num2,s1.num3,s1.num4);
	printf("%s\n%c\n%s\n%s",s1.num1,s1.num2,s1.num3,s1.num4);
	return 0;
} 

 这个程序是否能正常输入输出(num1,num2,num3,num4)正常存储?

经过试验,发现输入完num3后就会出现问题(输出num1+换行+num2+num3)

原因在于:%c能够识别任何字符并吃进去,前面有%s以换行为结尾,%s不能吃换行所以换行还残留在里面,所以%c实际上是换行字符

例题3:空间大小问题(4的倍数)

#include <stdio.h>

struct s{
	int num[20];
	char str[20];
	float num1;
	double num2;
}s1; 

struct t{
	int num[20];
	char str[17];
	float num1;
	double num2;
}t1;
int main()
{
	printf("%d\n",sizeof(s1));
	printf("%d",sizeof(t1));
	return 0;
}

例题4:结构体指针(结构示范,注意scanf部分)

#include <stdio.h>

struct s{
	int num[20];
	char str[20];
	float num1;
	double num2;
}; 
struct s s1;
struct s* p;

int main()
{
	p=&s1;
	for(int i=0;i<2;i++)
	{
		scanf("%d",&(*p).num[i]);
	}
	for(int i=0;i<2;i++)
	{
		printf("%d ",p->num[i]);
	}
	return 0;
}

例题5:嵌套

#include <stdio.h>

struct date{
	int month;
	int day;
	int year;
};
struct student{
	int num;
	char name[20];
	char sex;
	struct date birthday;
};
struct student s1;
int main()
{
	scanf("%d",&s1.birthday.year);
	printf("%d",s1.birthday.year);
}

10  文件

10.1  函数

fopen()   打开文件   

FILE  *fp;
    fp = fopen(文件名, 文件使用方式);

若文件打开成功,为该文件分配一个文件缓冲区和一个 FILE类型变量,返回一个FILE类型指针;   若文件打开失败,返回NULL。

文本文件的三种基本使用方式 :

“r”       为读(输入)文本文件打开文件。若文件不存在,返回NULL。

”w”:只写方式        为写(输出)文本文件打开文件。若文件不存在,则建立一个新文件;若文件已存在,则清空文件。

”a”:追加方式         为写(输出)文本文件打开文件。若文件已存在,则保持原来文件的内容,将新的数据增加到原来数据的后面;若文件不存在,则返回NULL。

二进制文件的三种基本使用方式 :

”rb”:只读方式        为读(输入)二进制文件打开文件。若文件不存在,返回NULL。

”wb”:只写方式        为写(输出)二进制文件打开文件。若文件不存在,则建立一个新文件;若文件已存在,则清空文件。

”ab”:追加方式         为写(输出)二进制文件打开文件。若文件已存在,则保持原来文件的内容,将新的数据增加到原来数据的后面;若文件不存在,则返回NULL。

文件的其他打开方式:

”r+”:可以对文本文件进行读/写操作。          若文件不存在返回NULL;          若文件存在内容不被清空。   

”w+”:可以对文本文件进行读/写操作。            若文件已经存在,则先清空文件原来的内容。     ”a+”:可以对文本文件进行读/追加操作。          文件内容不会清空。   

 ”rb+”:可以对二进制文件进行读/写操作。     

”wb+”:可以对二进制文件进行读/写操作。     

”ab+”:可以对二进制文件进行读/追加操作。

判断文件打开是否成功:

  //在打开一个文件时,如果出错,fopen将返回一个空指针值NULL
if(fp==NULL){
       printf("文件打开失败\n");
   }
   else{
       printf("文件打开成功\n");

主函数中exit(0);

子函数中return 0;

fclose()   关闭文件

FILE  *fp;
    fclose( fp );
        fp:已经打开的文件指针。

若文件关闭成功,则返回0;     若文件关闭失败,则返回非0值。

关闭文件及判断关闭是否成功:

 //文件正常关闭时,fclose() 的返回值为0,如果返回非零值则表示有错误发生。
  fclose(p2);
  int a=fclose(fp);//fclose()——fclose(文件指针)
  if(a==0){
      printf("文件关闭成功\n");
  }
  else{
      printf("文件关闭失败\n");
  }

一直输入直到EOF:

while ((c=getchar( ))!=EOF)
            /*键盘文件结束标志:输入Ctrl+z,显示^Z后回车*/
     putc(c, fp);                    /* 将键盘输入的字符写到文件中 */
fclose(fp);                          /* 建立文件结束,关闭文件 */
printf("outfile:\n");

feof()   检测文件是否结束

若该文件没有结束,则返回0;     若文件结束,则返回非0值。

fgetc()   从文件中读取一个字符

若输入操作成功,函数返回读入的字符;     若文件结束或输入操作失败,则返回EOF。

fputc()   把一个字符送到文件中

若输出操作成功,函数返回写入的字符;否则,返回EOF。

FILE  *fp;
    fputc( ch,fp );
       ch:需要输出的字符,可以是字符常量或字符变量;
       fp:文件指针变量。

fgets()   从文件中读取一个字符串

 fgets()用法为: char *fgets ( char *str, int n, FILE *fp );
​
str 为字符数组,n -1为要读取的字符数目,fp 为文件指针。

​

若输出操作成功,返回非0值;     若输出操作失败,则返回0。

fputs()   把一个字符串送到文件中

fputs(str,fp); 

若文件结束或输入操作失败,则返回NULL。

fprintf()   输出到文件中

FILE  *fp;
    fprintf( fp, 格式控制串,输出项参数表  );
       fp:文件指针变量。
       格式控制串和输出项参数表的规定和使用方法与printf函数相同。

若输出操作成功,返回写入的字节数;     若输出操作失败,则返回EOF。

fscanf()   从文件中读取 

FILE  *fp;
    fscanf( fp, 格式控制串, 地址表);
       fp:文件指针变量。
       格式控制串和地址表的规定和使用方法与scanf函数相同。

输入操作成功,返回实际读出的数据项个数,不包括 数据分隔符。若没有读数据项,则返回0。         若文件结束或调用失败,则返回EOF

fwrite( )    数据块输出函数

fwrite(p, size, n, fp);
       p:某类型指针;
       size:某类型数据存储空间的字节数(数据项大小);
       n:此次写入文件的数据项数;
       fp:文件指针变量。

 若输出操作成功,返回写入的数据项数;     若输出操作失败,则返回0。

fread( )   数据块输入函数

fread(p, size, n, fp);
       p:某类型指针;
       size:某类型数据存储空间的字节数(数据项大小);
       n:此次从文件中读取的数据项数;
       fp:文件指针变量。

若输入操作成功,返回实际读出的数据项个数。         若文件结束或调用失败,则返回0。

fseek( )    文件读写指针移动函数

fseek(fp, offset, whence);
       fp:文件指针变量;
       offset:位移量(字节,长整型);
       whence:起始位置标志。

fseek(fp,30,0)从文件开始位置向文件结束方向移动30个字节

fseek(fp,-10,1)    从当前位置向文件开始方向移动10个字节

fseek(fp,-8,2)从文件结束位置向文件开始方向移动8个字节 

若移动成功,返回0;     若移动失败,则返回非0值。

常量标识符     值     起始位置

SEEK_SET      0     文件开始位置

SEEK_CUR      1     文件读写指针当前位置

SEEK_END      2     文件结束位置

rewind( )   文件读写指针回绕函数

rewind( fp );
       fp:文件指针变量;

该函数无返回值。

ftell( )    文件读写指针位置函数

ftell( fp );
       fp:文件指针变量;

 若调用成功,则返回文件读写指针当前值(长整型);     若调用失败,则返回-1L。

ferror( )   文件操作错误函数

FILE  *fp;
    ferror( fp );
       fp:文件指针变量。

 若出错,则指示器置1,否则指示器置0。         函数返回错误指示器值。

clearerr( )   清除错误标志函数

FILE  *fp;
    clearerr( fp );
       fp:文件指针变量。

将文件的错误指示器和文件结束指示器清0。     该函数无返回值。

 10.2  示例

例题1:文件的w和r问题

第一部分:文件只能写,那么fprintf的作用就是把i和j的值打印到文件中,所以现在文件里有20 30

第二部分:文件只能读, 那么fscanf的作用就是从文件流中读取数据,读到了i和j对应的值(20和30),所以输出结果是20 30

11  static extern

11.1  extern

extern用于声明一个全局变量或函数,表示该变量或函数在当前文件所在的模块中并没有定义,需要从其他模块中引用。

// 文件1:file1.c
int num;  // 全局变量

// 文件2:file2.c
extern int num;  // 声明全局变量num的存在

void func() {
    printf("%d", num);  // 使用全局变量num
}
```

11.2  static

当static修饰全局变量时,改变作用域而不改变生存周期,意思是:static保证了这个变量不会被其他文件用extern声明,而不会影响其他

当static修饰局部变量时,改变生存周期而不改变作用域,意思是:static保证函数结束后这个变量的值不会被销毁

例题:阶乘

#include <stdio.h>

int factorial(int n) 
{
    static int result = 1;
    if (n < 0) 
	{
        printf("Error: Cannot calculate factorial of a negative number.\n");
        return -1;
    }
    else if (n == 0 || n == 1) 
	{
        return result;
    }
    else 
	{
        result *= n;
        return factorial(n-1);
    }
}

int main() 
{
    int n = 5;
    printf("%d! = %d", n, factorial(n));
    return 0;
}

static的作用是让result的值在出函数之后不会被销毁,会记住原先计算过的result值

12  二进制运算

12.1  逻辑运算符

操作符名称运算规则
&按位与1 1为 1 ,否则都为0
|按位或0 0得 0,否则都为1
^按位异或相同为0,不同为1
~按位取反各位都反转,1变0,0变1

12.2  位移运算(左移/右移)

左移运算符:<<
规则:把二进制各位数字左移n位,右补0
如:b=00001101<<3,即左移三位,得01101000

右移运算符:>>
规则:把二进制各位数字右移n位
如:b=00001110>>2,即右移两位,得00000011:10 

右移应注意符号问题:
无符号数,右移高位补0;
有符号数,符号位为0时(正数),左边补0;若为1时(负数),左边补0或1取决于计算机系统;补0为逻辑右移,补1为算术右移。 

13  基本概念

1.一个程序由一个或多个源程序文件组成。编辑后得到一个源程序文件(.c),经过编译得到目标程序文件(.obj),再将所有的目标模块输入计算机,与系统的库函数等进行连接,得到可执行的目标程序(.exe),最后把.exe输入计算机,能够运行

2.计算机不能直接识别高级语言程序,用一种称为编译程序的软件把用高级语言写的程序(源程序)转换为机器指令的程序(目标程序),然后让计算机执行机器指令程序,最后得到结果。高级程序的一个语句往往对应着多条机器指令

3.34种运算符,37种关键字,9种控制语句

if else 
switch
for
while
do while 
continue
break
return 
goto

4.C语言是完全模块化(函数)和结构化的语言

5.C语言允许直接访问物理地址,能进行位(bit)操作,能实现汇编语言的大部分功能

6.stdio是standard input&output的缩写

7.文件后缀.h的意思是头文件(header file)

8.在字符串中//和/*都不作为注释的开始,而作为字符串的一部分,注释可以用汉字或英文字符表示

9.

%后加的字母                                          代表的含义        

          %d                                               打印整型十进制数据

          %c                                               打印字符格式数据

          %f                                                打印float浮点数据

          %p                                               打印地址数据

          %x                                               打印十六进制数据

          %s                                               打印字符串

           %lf                                              打印double数据

           %e                                              以指数形式输出数据

           %g                                              根据大小自动选f格式或e格式,且不输出无意义的零

           %o                                               输出八进制数据

           %u                                               输出无符号十进制数据

           %ld                                              输出长整型


10.源程序文件包括预处理指令,全局声明,函数定义

11.函数是C语言主要组成部分

12.一个函数包括函数首部和函数体,函数体包括声明部分和执行部分

13.C语言本身不提供输入输出语句

14.程序文档是软件的一个重要组成部分,软件是计算机程序和程序文档的总称

15.一个程序可能包含若干个源程序文件,编译是以源程序文件为对象的

16.一个程序主要包括对数据的描述(数据结构)和对操作的描述(算法)

17.程序=数据结构+算法

18.计算机算法分为数值运算算法和非数值运算算法,计算机在非数值运算方面的应用远远超过了在数值运算方面的应用

19.算法的特点是有穷性,确定性,有零个或多个输入,有一个或多个输出,有效性

20.表示算法有自然语言,传统流程图,结构化流程图和伪代码

21.N-S图是结构化流程图

22.三种基本结构:顺序结构、选择结构、循环结构(当型、直到型)

23.数据包括常量(整型,实型,字符(普通字符和转义字符),字符串,符号),变量,常变量(const),标识符

24.标识符必须以字母或下划线开头,并且可以包含字母、下划线和数字

25.符号常量不占内存,只是一个临时符号

26.变量必须先定义后使用

27.C语句包括控制语句,函数调用语句,表达式语句,空语句,复合语句

28.+(正号)和-(负号)属于单目运算符,+(加号)和-(减号)属于双目运算符

29.优先级:! > 算术运算符 > 关系运算符 (等于和不等于优先级略低)> && > || > 赋值运算符

30.凡是二元运算符都可以与赋值符一起组合成复合赋值符

31.赋值运算符左侧应该是一个可以修改值的左值,变量可以作为左值,但是算术表达式和常量就不能作为左值,凡是左值都可以作为右值

32.一般变量初始化不是在编译阶段完成的,只有静态存储变量和外部变量的初始化是在编译阶段完成的

33.#include<stdio.h>和“stdio.h”的区别:后者先从用户的当前目录中寻找,若找不到再按标准方式查找

34.printf包括格式控制(格式控制字符串,格式字符串,包括格式声明和普通字符),输出表列   scanf包括格式控制,地址表列

35.%-m.nf左对齐

36.Switch语句是多分支选择语句 

37.switch一般形式中括号内的表达式,其值的类型应为整数类型(包括字符型)

38.可以没有default符号,switch下面的花括号是一个复合语句,每一个case常量必须互不相同,case标号只起标记的作用,case字句中可以不必用花括号括起来

39.

40.循环结构又称重复结构 

41.三种基本结构:顺序结构、选择结构、循环结构

42.循环变量赋初值、循环条件、循环变量增值

 43.凡用while循环能完成的,用for循环都能实现

44.数组是一组有序数据的集合

45.常量表达式中可以包括常量和符号常量,int【3+5】是有效的,int【n】是无效的

int n;
scanf("%d",&n);
int a[n];//这种是无效的

46.二维数组常称为矩阵

47.

以下不能对一维数组a进行正确初始化的语句是( B)。

  • A. int a[10]={0,0,0,0,0};
  • B. int a[10]={ };
  • C. int a[]={0};
  • D. int a[10]={10*1};

48. '\0'代表ASCII码为0的字符

49.程序就是一组计算机能识别和执行的指令

50.一个源程序文件由一个或多个函数以及其他有关内容(如指令、数据声明与定义等)组成 

51.在程序编译时是以源程序文件为单位进行编译的,而不是以函数为单位进行编译的

52.main函数是被系统调用的,函数间可以互相调用,定义函数之间是平行关系

53.函数有库函数用户自己定义的函数两种

54.从函数的形式看,函数分无参函数有参函数

55.所有函数必须先定义后使用 

56.定义函数应包括指定函数的名字、指定函数的类型、指定函数的参数的名字和类型、指定函数应该完成什么操作(函数的功能)

 57.在定义函数时函数名后面括号中的变量名称为“形式参数”(形参、虚拟参数),在主调函数中调用一个函数,函数名后面的括号中的参数称为“实际参数”(实参),实际参数可以是常量、变量或表达式,但要求他们有确定的值

58.在调用函数过程中发生的实参与形参之间的数据传递称为“虚实结合” 

59. 在定义函数中指定的形参,在未出现函数调用时,它们并不占内存中的存储单元,在发生函数调用时,函数的形参才被临时分配内存单元,调用结束,形参单元被释放

60. 实参向形参的数据传递是“值传递”,单向传递,只能由实参传给形参,实参和形参在内存中占有不同的内存单元,实参无法得到形参的值

61. void类型又称空类型

62.声明: 

 写函数声明时,可以简单照写已经定义的函数的首行,再加一个分号,就成了函数的声明,函数的首行(函数首部)称为函数原型

63.在函数声明中的形参名可以省写,只写形参的类型 

64.函数的定义和声明不是一回事,函数的定义是指对函数功能的确立,包括指定函数名、函数值类型、形参及其类型以及函数体等,它是一个完整的、独立的函数单位。而函数的声明的作用则是把函数的名字、函数的类型以及形参的类型、个数和顺序通知编译系统,它不包含函数体 

65.在调用一个函数的过程中又出现直接和间接地调用该函数本身,称为函数的递归调用 

66.数组元素可以用作函数实参,但不能用作函数形参,因为形参是在函数被临时调用时临时分配存储单元的

67. 

定义average函数行指定array数组的大小是没有意义的,只是起获得地址作用,所以可以这样写: 68.C语言允许用指针变量(float *array)或数组(float array【】)作为形参,二者是等价的,对数组元素的访问,用下标法和指针法是完全等价的

69.用数组名作函数实参时,不是把数组元素的值传递给形参,而是把实参数组的首地址传给形参数组,这样两个数组就共占一段内存单元 

70.主函数中定义的变量也只在主函数中有效,主函数也不能使用其他函数中定义的变量,不同函数中可以使用同名的变量,它们代表不同的对象,互不干扰,在内存中占有不同的单元

 71.在一个函数内部,可以在复合语句中定义变量,这些变量只在本复合语句中有效,这些复合语句称为“分程序”或“程序块”

72.在函数内定义的变量是局部变量,在函数外定义的变量是全局变量(外部变量、全程变量) 

73.C的存储类别包括四种:自动的(auto)、静态的(statis)、寄存器的(register)、外部的(extern)

74.静态存储变量属于静态存储类别,在静态存储区内分配存储单元 

75.静态局部变量是在编译时赋初值的,即只赋初值一次,以后每次调用函数时不再重新赋初值而只是保留上次函数调用结束的值

76.静态存储多占内存

77.如果一些变量使用频繁,允许将局部变量的值放在CPU的寄存器中,需要用时直接从寄存器取出参加运算,不必再到内存中去存取,这种变量叫寄存器变量

78.全局变量都是存储在静态存储区中的

79.extern 

 

 80.static

 81.对一个数据的定义,需要指定两种属性:数据类型和存储类别

 82.

 

 83.作用域是从空间的角度理解,生存期是从时间的角度理解

作用域用可见或者不可见来说明,生存期用存在或者不存在来说明 

84.声明包括定义,但并非所有的声明都是定义,声明分为定义性声明(定义,建立存储空间)和引用性声明(不建立存储空间)

85.地址指向该变量单元,因此将地址形象化地称为指针

86.整数以补码形式存放,实数以指数形式存放

87.C语言中的地址包括位置信息(内存编号,纯地址)它所指向的数据的类型信息,或者说他是带类型的地址

88.一个函数只能被本文件中其他函数调用,称为内部函数(静态函数)

一个函数能被其他文件中的函数调用,称为外部函数

89.对变量的访问都是通过地址进行的

90. 直接按变量名进行的访问,称为直接访问

91.区分指针和指针变量:92.指针变量是基本数据类型派生出来的类型

93.在定义指针变量时必须指定基类型 

94.使用指针法能使目标程序效率提高,占内存少,运行速度快

95.【】实际上是变址运算符,即将a【i】 

96.p2-p1有意义,p2+p1无意义

97. *p++从右往左结C合,代表取p的值后指针往后挪一位

98.C语言只有字符变量,没有字符串变量

99.

100.

这种称为可变格式输出函数 

101.C语言允许用户自己建立由不同类型数据组成的组合型的数据结构,称为结构体

102.花括号内是该结构体所包括的子项,称为结构体的成员

103.成员表列也称为域表,每一个成员是结构体中的一个域 

104. 文件包括程序文件(包括源程序文件.c、目标文件.obj、可执行文件.exe)数据文件

105. 操作系统把各种设备都统一作为文件来处理

106.文件一般指存储在外部介质上数据的集合 

107.常将输入输出形象地称为,即数据流 

108.流表示了信息从目的端的流动 

109.文件是由操作系统统一管理的

110.C语言把文件看作一个字符(或字节)的序列,即由一个一个字符(或字节)的数据顺序组成。一个输入输出流就是一个字符流或字节(内容为二进制数据)流。 

111.C的数据文件由一连串的字符(或字节)组成,而不考虑行的界限,两行数据间不会自动加分隔符,输入输出流的开始和结束仅受程序控制而不受物理符号(如回车换行符) ,这种文件称为流式文件

112.文件标识包括三部分:文件路径、文件名主干、文件后缀

113. 文件标识常被称为文件名

114.数据文件可分为ASCII文件(文本文件)二进制文件(映像文件)

115.ANSIC标准采用缓冲文件系统处理数据文件,系统自动开辟文件缓冲区,装满缓冲区后才一起送到磁盘

116.FILE其实是一个结构体变量

117.指向文件的指针变量并不是指向外部介质上的数据文件的开头,而是指向内存中的文件信息区的开头 

118.程序中可以使用三个标准的流文件:标准输入流(stdin)、标准输出流(stdout)、标准出错输出流 (stderr)

119.EOF当做-1 

120.121.C语言中运算符的结合性通常都为从左到右,但是有三类运算符是从右到左的:单目运算符、赋值运算符、三目条件运算符

122.以下叙述中正确的是(A)
A、当对文件的读(写)操作完成之后,必须将它关闭,否则可能导致数据丢失(用fclose函数关闭)
B、打开一个已存在的文件并进行了写操作后,原有文件中的全部数据必定被覆盖(打开方式为a表示追加)
C、在一个程序中当对文件进行了写操作后,必须先关闭该文件然后再打开,才能读到第1个数据(用rewind指针回绕函数或者用fseek定位函数移动指针)
D、C语言中的文件是流式文件,因此只能顺序存取数据(可以用fseek从指定位置开始读写)

123.以下错误的定义语句是(C)
A. int x[][3]=({0},{1},{1,2,3}};
B, int x[4][3]={{1,2,3},{1,2,3},{1,2,3},{1,2,3}};
C. int x[ 4] [ ] ={{1,2,3},{1,2,3},{1,2,3},{1,2,3}};
D,intx[][3]={1,2,3};

 行号可以省略,列号不能省略

124.注意输出结果

#include <stdio.h>
int a[][3]={1,3,5,4};
int main()
{
	for(int i=0;i<3;i++)
	{
		for(int j=0;j<3;j++)
		{
			printf("%d ",a[i][j]);
		}
		printf("\n");
	}
	printf("%d",sizeof(a));
	return 0;
}

125.注意输出结果

#include <stdio.h>
#include <string.h>
char p1[]={'a','b','c'};
char p2[10]={'a','b','c'};
int main()
{
 printf("%d\n",strlen(p1));
 printf("%d\n",sizeof(p1));
 printf("%d\n",strlen(p2));
 printf("%d\n",sizeof(p2));
 return 0;
}

p1数组,存了三个字符,所以只有三个空间,注意后边没有\0,字符串以\0结尾,但后边没有\0,所以第一个输出结果是不确定的,第二个输出3

p2数组,存了三个字符,但是总共开个十个字符的空间,所以后面7个空间默认是\0,空间大小是10

126.操作系统把各种设备都统一作为文件来处理

127.函数调用的形式:函数调用语句、函数表达式、函数参数

  • 17
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菜只因C

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值