欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

c语言基础知识

程序员文章站 2024-03-15 12:36:47
...

一、常量变量

1.常见的一些数据类型

int 4字节,short 2字节,long 4字节(跟平台有关,可能是4,也可能是8),longlong 8字节, char 1字节,float 4字节,double 8字节

2.字符串

是由双引号引起来的一串字符,以/0作为结束标志。

‘/0’不是字符串的内容,只是一个结束标志,所以strlen时不会求‘\0’的长度

char arr[] = {'h','e','h','e'};

printf("%s", arr); //%s是以字符串形式输出,遇到‘/0’停止,但是arr[]数组中没有‘/0’,所以就会继续访问后面的内容,知道遇到‘/0’为止,所以会访问内存出错

c语言基础知识

3.const关键字

  • 在c语言中:当const修饰一个标识符的时候,这各标识符依然是一个变量,只是具有常属性,不能被直接改变
  • 在C++中,const修饰一个标识符时,编译器会自动将其设置未寄存器变量,当使用指针取修改时,改的时内存里面的值,所以寄存器中存储的值仍然不会被改变
        const int sz = 10;
	int * p = (int*)&sz;
	*p = 20;
	printf("%d", sz);   //10
       	volatile const int sz = 10;
	int * p = (int*)&sz;
	*p = 20;
	printf("%d", sz);//20

volatile:保证内存的可见性,让变量的每次取值都去内存里去取,这样就可以改变sz的值了

4.define:是一个指令,并不是一个关键字

#define PAI 3.14

5.枚举:enum关键字,枚举常量的值会依次增加,如果不指定就从0开始加,如果指定,就从指定值开始增加

enum Sex
{
	MALE,
	FEMALE,
	SECRET
};

c语言基础知识

enum Sex
{
	MALE=20,
	FEMALE,
	SECRET
};

c语言基础知识

6.register关键字:会将变量存储在寄存器内,不能对其进行&操作,因为编址是针对内存的。register只是一个建议。

7.fflush(stdin)/fflush(stdout):清空输入输出缓冲区

8.static关键字:

局部变量:改变其生命周期(存储位置:栈->静态区)

全局变量:改变其链接属性(作用域)

9.初始化:

全局变量:默认初始化为0

局部变量:必须自己初始化(随机值)

10:printf()函数返回值:返回打印字符的个数

        int i = 43;
	printf("%d", printf("%d", printf("%d", i)));

c语言基础知识

i是43,其返回值是2,外层printf()输出的值为2,输出2后返回值为1,所以最外层的printf()返回1,即4321;

二、分支语句

1.if语句:else语句总是跟在其之前未配对的最近的if匹配

if语句书写规范:

  • bool和零值比较:if(flag),if(!flag),不能使用if(flag==TRUE)/if(flag==FALSE),flag是个整数,可以被赋值为2,3,等如何非0数字来表示真,而TRUE,FLASE只有一个固定的值
  • 整形变量和零值比较:if(n==0),if(n!=0)
  • 指针变量和零值比较:if(p==NULL),if(p!=NULL)
    • 指针使用时要注意:1.初始化为NULL 2.使用之前判空
        int *p = NULL;
	if (p != NULL)
	{
		*p = 20;
	}
  • 浮点数与零值比较:#define EXP 0.0000000001 ,if((f>-EXP)&&(f<EXP))

2.switch语句:switch,case语句中,case后必须为整形的常量表达式。

switch语句中,我们没有办法实现分支,搭配break才能实现真正的分支。

最好在最后加上default语句,甚至可以在后边也加一个break

三、循环语句

1.break与continue:

whlie语句中:break:永久跳出循环,continue:终止本次循环,跳到while语句的判断部分

for语句中:break:永久跳出循环,continue:跳出循环体,到调整部分

2.while语句:

	int i = 1;
	while (i <= 10)
	{
		if (i == 5)
			break;
		printf("%d", i);
		i = i + 1;
	}

//输出1 2 3 4

int i = 1;
while (i <= 10)
{
    if (i == 5)
      continue;
    printf("%d", i);
    i = i + 1;
}

//输出1 2 3 4 在i=i+1,之前就跳出循环了所以i一直为5,然后陷入死循环

int i = 1;
while (i <= 10)
{
    i = i + 1;
    if (i == 5)
      continue;
    printf("%d", i);
}

//输出 2 3 4 6 7 8 9 10 11,没有5

 

3.for循环的一些变形

        int i = 0;
	int j = 0;
	for (; i < 10; i++)
	{
		for (; j < 10; j++)
		{
			printf("hehe\n");
		}
	}

//输出10个“hehe”,i=0进入循环直到j=10,共十次,下次i=1进来时,j=10不进入循环

注:编程时要特别注意不要将==误写为=;

for (i=0,j=0; i < 2,j<5; i++,j++)
{
    printf("hehe\n");
}

//输出5个“hehe”,i<2,j<5;是一个逗号表达式,逗号表达式从左向右求值,结果为最后一个表达式的值

for (i = 0, j = -1; j = 0; i++, j++)
{
    j++;
    printf("hehe\n");
}

//不输出,k=0,给k赋值为0,0为假,不进入循环

for (;;)
{
    printf("hehe\n");}

//判断条件为空,默认为真,陷入死循环

for (i=0,j=0;i+j<10;++i,j++)
{
    printf("hehe\n");
}

//输出五个hehe

4.循环效率

在多重循环中,如果有可能,要将最长的循环放在内层,最短的循环放在外层,以减少CPU跨切循环层的次数

循环体内部存在逻辑判断,并且次数很大的,宜将逻辑判断放在循环体外面

四、操作符与表达式

1.算术操作符:+ - * % (只能用于俩个整数)/(可用于整数与浮点数)

2.位移操作符:

左移:末尾补零

右移:逻辑右移:补零,算术右移:补符号位

3.位操作符:&:按位与,|:按位或,^:按位异或(俩个相同的数字异或结果为0,不同为1)

注:他们的操纵数必须时整数

4.单目操作符:sizeof(以字节为单位,不是关键字) &:取地址

5.sizeof使用注意事项:

        int a = 10;
	printf("%d",sizeof(a));
	printf("%d", sizeof a);
	//printf("%d", sizeof int);  
	printf("%d", sizeof(int));

注:sizeof在求变量所占空间大小时,用变量名可以去掉(),用类型时,不能去掉(),但是我们建议不去掉()

	int a = 1;
	short s = 3;
	printf("%d\n", sizeof(s = a + 5));
	printf("%d\n", sizeof(s));
	printf("%d\n", s);

c语言基础知识

注:sizeof内部的表达式不参与运算

6.数组名单独放在sizeof内部表示整个数组;&数组名:表示整个数组

7.逻辑操作符:

&&:逻辑与,俩边有一个为假,则表达式结果为假,若左边为假,后面的即不参与运算

||:逻辑或,俩边有一个为真即为真,若左边为真,后面的即不参与运算

例:

        int i = 0, a = 1, b = 2, c = 3, d = 4;
	i = a++&&++b&&d++;
	printf("a=%d,b=%d,c=%d,c=%d", a, b, c, d);

c语言基础知识

	int i = 0, a = 1, b = 2, c = 3, d = 4;
	i = a++||++b||d++;
	printf("a=%d,b=%d,c=%d,c=%d", a, b, c, d);

c语言基础知识

8.三目操作符: exp1?exp2:exp3

找俩个数里大的一个

int a = 10;

int b = 20;

int i = a > b ? a : b;

printf("%d", i);

9.逗号表达式:从左向右求值,整个表达式的结果为最后一个表达式的结果

10.表达式的求值结果有三个影响因素:

1)操作符的优先级

2)操作符的结核性

3)是否控制求值顺序

五、函数

1.传参:

值传递:形参是实参的一份临时拷贝,形参和实参分别占有不同的内存块,对形参的修改不会影响实参

传址:形参和实参依然占有并不太的存储空间,但是俩者直接有一层联系,形参里存放的是实参的地址,这样就可以通过对形参的间接访问操作实参。

2.链接属性:在程序链接时起作用

1)外部链接属性:全局标识符具有外部链接属性,外部链接属性意味着,一个标识符,不仅可以在当前源文件使用,使用exetrn的声明也可以在其他源文件使用

2)内部链接属性:只能在当前源文件内使用,具有外部链接属性的标识符加上一个static关键词修饰就会变成内部链接属性

static:修饰变量:全局——改变链接属性(外部链接属性->内部链接属性)

局部——改变存储位置——从而改变生命周期

修饰函数:链接属性(外->内)

3)无属性(局部变量,出了作用域即失效,所以无链接属性)

六、数组

1.数组是一组相同类型元素的集合,数组创建时[]内必须是一个常量,不是使用变量

2.数组创建时,如果不想指定数组的大小,就得初始化,数组的元素个数根据初始化的内容定下来

3.数组名代表数组首元素的地址

        char arr1[] = "abcdef";
	char arr2[] = "abcdef";
	if (arr1 == arr2)
		printf("hehe\n");

c语言基础知识

//数组名代表首元素的地址,俩个数组中“abcdef”的地址不同,所以不输出

        char *p1 = "abcdef";
	char *p2 = "abcdef";
	if (p1 == p2)
		printf("hehe\n");

 c语言基础知识

//输出hehe,p1和p2指向同一块地址

4.数组的使用:

int *p = arr;

&arr[i] <==> p+i <==> p[i]

arr[i] <==> *(p+i) <==>*(arr+i)

5.指针:可以理解为一个变量,时一个专门用来存放地址的变量

在32位平台下时4字节,64位平台下8字节