c语言基础知识

一、常量变量

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’为止,所以会访问内存出错

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
};

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

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

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

8.static关键字:

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

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

9.初始化:

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

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

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

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

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);

注: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);

	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);

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");

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

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

 

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

4.数组的使用:

int *p = arr;

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

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

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

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

  • 38
    点赞
  • 213
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值