栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C语言学习笔记

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C语言学习笔记

数据 常量 大分类
  1. 字面常量: 直观写出来的值
  2. const修饰发常量
  3. #define定义的常量
  4. 枚举常量
常量,const常变量

int main()
{
    const int num = 1;\const 表示常属性变量的创建
    num = 8;
    return 0;
}
​

是不能运行的

int main()
{
    const int n = 4;
    printf("%dn", n);
    int arr[n] = { 0 };
    return 0;
}
​
int main()
{
    const const int n = 4;
    printf("%dn", n);
    int arr[n] = { 0 };
    return 0;
}

都不能运行, const int n表示n是一个具有常属性的变量,不是常量.

#define _CRT_SECURE_NO_WARNINGS 1
#include
#define MAX 10
int main()
{
    int arr[MAX] = { 0 };
    return 0;
}

这个可以运行,因为#define定义了一个标准常量

枚举常量
enum Sex\枚举常量
{
    MALE,
    FEMALE,
    SECRET
};//枚举常量的可能取值, 大括号内给定的枚举常量是不能改变的, 枚举变量是可以改变的
int main()
{
    printf("%d",MALE);//0
    printf("%d",FEMALE);//1
    printf("%d",SECRET);//2
}
字符串+转义字符+注释 字符串

多个字符放在双引号内就是字符串 "hello bitn"

int main()
{
"abcdef";//字符串
"";//空字符串
return 0;
}

#define _CRT_SECURE_NO_WARNINGS 1
#include
int main()
{
    char arr1[] = "abc";
    //"abc"--'a','b','c','' =>''表示字符串的结束标志,''的值是0
    //char arr2[] = { 'a','b','c' };'c'的后面应该加上一个0
    char arr2[]={'a','b','c',0};
    printf("%sn", arr1);
    printf("%sn", arr2);
    printf("%dn", strlen(arr1));
    printf("%dn", strlen(arr2));//打印字符串长度,3
    return 0;
}

数据在计算机上存储的是二进制,字符是以ASCII编码储存.

转义字符

 n把本义变了,使某一个字符不再是原来的意思,表示换行

#define _CRT_SECURE_NO_WARNINGS 1
#include
int main()
{
    printf("abcn");
    return 0;
}

t叫水平制表符,类似Tab键

注释

c的注释 c++的注释//` 都可以用 注释用于代码难懂的地方

输入输出

格式字符
格式符号作用
i, d十进制整数
x, X十六进制无符号整数
o八进制无符号整数
u无符号十进制整数
c单一字符
s字符串
e指数形式浮点小数
f小数形式浮点小数
#include
int main()
{
    float f=3.1415926;
    printf("%2.3fn",f);
    printf("%fn",f);
    return 0;
}

其中%2.3f2表示格式(被超过了就忽略), 3表示保留小数点位数(四舍五入)

修饰符功能
m输出数据域宽,数据长度
.n对实数,指定小数点后位数(四舍五入)
对字符串,指定实际输出位数
-输出数据在域内左对齐(缺省右对齐)
+指定在有符号数的正数前显示正号(+)
0输出数值时指定左面不使用的空位置自动填0
#在八进制和十六进制数前显示前导0,0x
l在d, o, x, u前,指定输出精度为long型
l在e, f, g前,指定输出精度为double型
字符输入函数

putchar()

scanf() 如果需要提示语句, 单独写一行printf, 不能写在scanf中

输入函数留下的垃圾

即输入一个整型值后紧接着按回车输入另一个字符, 会将回车变成输入. 清除的方法有

1. 用getchar()吃掉
1. %[空格]c或%*c
字符串输入函数
  1. gets(s)
  2. scanf()会将空格作为字符串输入的结束标志(处理连续字符输入时可以处理空格)
字符串输出函数

puts

会自动换行

运算符 算数运算符

加 减 乘 除(/) 取余(%) 取余不能给浮点数进行.

关系运算符

>``>=``<=``<

==``!=

逻辑运算符
  1. !取反: 1变 0,0变1
  2. ||或
位运算符

针对二进制的位(0/1)

位运算可以以任何数据类型

运算符功能说明
~位逻辑反转换为二进制, 然后0 1 互换
&位逻辑与
|位逻辑或
^位逻辑亦或相异为真, 相同为假
>>右移位
<<左移位乘二
特殊运算符 赋值运算符

 

条件运算符? 逗号运算符

z=(x+=5,y=x+0.2)

z的值由最后一个表达式决定

运算符的优先级

建议多加括号解决优先级问题

#include
int main()
{
	int x = 1, y = 0, z = 0;
	x += y == z,y = x + 2, z = x + y + x > 0;
	printf("%d,%d,%dn", x, y, z);
	return 0;
}
补充

解引用运算符*的优先级要小于下标运算符[], 因此表示数组指针需要加括号例如int (*p)[10]

数组 一维数组

C语言中不会对数组做越界判断, 需要自己限制

  1. 数组如果不初始化, 值是随机的.
  2. static数组元素不赋值, 默认是0
  3. 只给部分赋值, 后面默认0
  4. 初始化给多了直接报错
例题: 冒泡排序
#include
int main(int argc, char const *argv[])
{
	int a[7]={49,38,97,76,13,27,30};
		int i = 0,j=6,temp;
	for (;j>=0;j--)
	{
		for(i=0;i<=j;i++)
			{
				if(a[i]>a[i+1])
				{
					temp = a[i];
					a[i] = a[i+1];
					a[i+1] = temp;
				}
			}
			
	}
	for(i=0;i<=6;i++)
		{
			printf("%dn",a[i]);
		}

	return 0;
}
二维数组

P[行][列]

定义方式: 行数可以省略, 列数不可以

二维数组的存储

二维数组存储的验证

#include
int main(int argc, char const *argv[])
{
	int a[4][5]={{1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15},{16,17,18,19,20}};
	for(int x = 0; x < 4; x++)
	{
		for(int y = 0; y < 5; y++)
		{
			printf("The id of a[%d][%d] is %pn",x,y,&a[x][y] );
		}
	}
	return 0;
}
多维数组

例题: 打印杨辉三角的前十行
#include

int main(int argc, char const *argv[])
{
	int a[10][10];
	for(int x = 0; x < 10; x++)
		{
			for(int y = 0; y < 10; y++)
			{
				if(y == 0 ||x == y)
					a[x][y]=1;

			}
		}
	for(int x = 2; x < 10; x++)
	{
		for(int y = 1; y < x; y++)
		{
			a[x][y]=a[x-1][y-1]+a[x-1][y];
		}

	}
	for(int x = 0; x < 10; x++)
	{
		for(int y = 0; y <= x; y++)
		{
			printf("%d ",a[x][y]);
		}
		printf("n");
	}
	return 0;
}
字符数组和字符串

C语言中, 字符串依附于字符数组存在

初始化
  1. 逐个元素赋值
  2. 字符串赋值 "abc" ->a, b, c,
    0 NULL都是一回事, ASCII码值是0

, '0'是另一回事, ASCII码值是48

二维数组下的字符串数组
#include
int main()
{
	char fruit[][20] = { "bannana","apple","strawmerry","watermelen" };
	int i, j, n, m;
	n = sizeof(fruit) / sizeof(fruit[0]);
	m = sizeof(fruit[0]) / sizeof(fruit[0][0]);

	for (i = 0; i < n; i++)
	{
		for (j = 0; j < m; j++)
		{
			putchar(fruit[i][j]);
		}
		putchar('n');
	}
	return 0;
}

sizeof()得到的是总空间, 包括未赋值部分, strlen得到的是实际的字符串长度(需要string.h>)

字符串函数 常见字符串函数  strlen求长度

计算一个字符串的实际长度(不包含), 返回的是字节数, 往往一个char就是一个字节, 因此可以视为长度

char s[10] = { 'A', 0, 'b', '', '0' };
printf("%zd", strlen(s));//这将返回1, 因为遇到0, 就认为字符串结束了
printf("%d", sizeof(s)/sizeof(char));//这将返回10, 表示整个数组

遇到特殊字符时:

char s[20] = "ttnasdczx0qwe";
printf("%zdn", strlen(s));//返回10  t,n分别被视为一个字符
printf("%d", sizeof(s)/sizeof(char));//返回20
char s[20] = "x69141n"; // xhh表示十六进制数代表的符号, ddd表示八进制数代表的符号 一般不建议这样写
printf("%zdn", strlen(s));
strcpy字符串拷贝
  1. strcpy(字符数组1,字符数组2)
  2. 将字符串2拷贝到字符串1中去, 返回字符数组1的首地址.(必须是字符串)
  3. 字符数组1必须足够大
strcat字符串连接函数
  1. strcpy(字符数组1,字符数组2)
  2. 将字符串2连接到字符串1后面, 返回字符数组1的首地址.(必须是字符串)
  3. 字符数组1必须足够大
  4. 连接之前,二者都是以''结束的, 连接后 串1的'取消,新串最后加''
strcmp字符串比较函数

strcmp(字符串1,字符串2)

  1. 比较规则: 两个字符串从左到右依次比较ASCII码值, 若1<2 返回负整数, 若1==2返回0, 若1>2返回正整数.
  2. 如果长度不等, 空的位置相当于和比 ,
注意: 字符串函数的使用前提必须是字符串或带''的字符数组, 否则将出现不可以预知的问题. 字符串函数的扩展用法 strncpy(p,p1,n)复制指定长度的字符串 strncat(p,p1,n)连接指定长度的字符串 strcasecmp忽略大小写比较字符串 strncmp(p, p1, n) 比较指定长度字符串 strchr(p, c) 在字符串中查找指定字符
#include

#include
int main(int argc, char const* argv[])
{
	char s1[]="123aeqw$asdsa";
	int ch;

	ch='$';

	printf("%p,%p,nn",s1,strchr(s1,ch));	
	return 0;
}

strstr(p, p1) 查找字符串

#include
#include
int main(int argc, char const* argv[])
{
	char s1[]="how are you";
	char s2[]="are";
	printf("%ldn",strstr(s1,s2)-s1);
	return 0;
}
关于字符的函数, 需要#include

isalpha() 检查是否为字母字符 isupper()检查是否为大写字母字符 islower() 检查是否为小写字母字符 isdigit() 检查是否为数字 指针

在C语言中, 内存单元的地址叫指针. 在不影响理解的情况下, 地址, 指针, 指针变量不做区分.

指针运算
  1. 只限于指向相同类型的指针
  2. 指针相减得到的是所隔数据的个数, 不是地址差.
赋值

可以将地址赋值给指针.

解引用

*运算符给出指针指向地址上的存储的值

取址

和所有变量一样,指针变量也有自己的地址和值. &运算符给出指针本身的地址.

指针与整数相加

整数都会和指针指向类型的大小相乘, 再把结果与初始地址相加.

递增指针

递增指向数组元素的指针可以让该指针移动到数组的下一个元素. 因此ptr1指向urn[1].

指针减去一个整数

指针必须是被减数. 其余与加法类似.

递减指针

类似递增, 用于数组

指针求差 指针与数组

数组名是指向数组第一个元素的指针.

二维数组中的指针
int a[3][2]={{1,6},{9,12},{61,12}};
int *p,i,n;

n=sizeof(a)/sizeof(int);
p=a;//warning

这样写是不对的, a与p类型是有区别的, 一个p指向四个字节, 但是一个a指向8个字节, 应该这样:

p=a[0]

也就是说 如果需要用一级指针遍历二维数组, 需要for循环

二维数组由多个数组构成,

上述代码中a就是由a[0] a[1] a[2] 三个数组构成.

对二维数组名进行一次解引用将得到指向一行数的指针.

字符指针与字符串

如果直接让指针指向字符串

char *p="hello world";

指针存储了字符串常量的起始地址, 不能用指针修改 指向对象的值了. 对于数组则不能这样做, 这也是字符串与字符数组的区别.

指针数组

若干个存储类型相同的指针变量构成的数组.

double *pa[2], a[2][3]

*只管一个

指针数组可以用于对二维数组.

 

多级指针 void指针
 void * [指针名] 

可以通过强制类型转换变为其他类型的指针

显示转换 隐式转换

显式调用是指在代码中调用 隐式调用是编译器后台调用

函数 定义和用法

l函数是一个完成特定功能的代码模块,其程序代码独立,通常要求有返回值,也可以是空值。大括号内称为函数体

l一般形式如下:

<数据类型> <函数名称>( <形式参数说明> ) {

​      语句序列;

​      return[(<表达式>)];

} 

例如

double p(int x);
调用

函数名(实际参数)

实参就是在使用函数时,调用函数传递给被调用函数的数据。需要确切的数据

函数调用可以作为一个运算量出现在表达式中,也可以单独形成一个语句。对于无返回值的函数来讲,只能形成一个函数调用语句。

参数传递 (C语言没有引用)

传递数组参数(非字符串)需要同时传递数组的大小.

复制传递方式

实参的值赋值给形参

  1. 调用函数将实参传递给被调用函数,被调用函数将创建同类型的形参并用实参初始化
  2. 形参是新开辟的存储空间,因此,在函数中改变形参的值,不会影响到实参
指针函数 指针函数的用法

指针函数是一个返回值为指针的函数.

函数中的空间会在结束时释放, 这造成指针无法再访问, 可以将函数内变量申请为static变量延长试用期.

或使用 字符串常量:

char *str = "hello"

但是不能修改*str

总的来说, 指针函数的返回可以是:

  1. 全局变量的地址
  2. static变量的地址
  3. 字符串常量的地址
  4. 动态内存
递归函数和函数指针 递归即递推加回归

例子1: 求阶乘

#include
int calcu(int x);
int main()
{
	printf("%dn",calcu(10));
	return 0;
}
int calcu(int x)
{
	if (x==0)
	{
		return 1;
	}
	double factorial = x;
	factorial*=calcu(x-1);
	return factorial;
}

例子2: 斐波拉契数列

int main()
{
	for(int num = 1; num <= 10; num++)
	{
		printf("%dn",fib(num));
	}
	return 0;
}
int fib(int x)
{
	int fibx;
	if (x == 1 || x == 2)
	{
		return 1;
	}
	fibx = fib(x-1)+fib(x-2);
	return fibx;
}
函数指针

函数指针的核心是一个指针, 存储函数的地址

函数地址代表了函数的入口地址( 函数名)

#include
int add(int, int);

int main()
{
	int m = 10,n = 20;
	int (*p)(int ,int );
	p=add;
	printf("%dn",p(m,n));
	return 0;
}
int add(int x,int y)
{
	return x+y;
}

函数指针要与函数产生关系, 因此需要返回值类型和参数列表和函数的原型一致, 这里注意解引用 *的优先级, 需要加()

函数指针数组

数组中函数指针指向函数的返回类型和参数列表一致.

例子: 调用qsort进行排序
#include
#include
int stol(const void *x, const void *y);

int main()
{
	int a[10] = {5.7,3,6,4,2,8,9,1};
	qsort(a,sizeof(a)/sizeof(int),sizeof(int),stol);
	for(int k = 0; k<= 9; k++)
	{
		printf("%dn",a[k] );
	}
	return 0;
}
int stol(const void *x, const void *y)
{
	return *(int *)x - *(int *)y;
}
资源&更深入的阅读资料: 领取资料的神秘通道开启点击链接加入群聊【C语言/C++编程学习基地】:828339809
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/937954.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号