编程导航

标准输入输出

  “stdio” 的全称是 “standard input/output”,表示标准输入输出,例如 “printf” 打印函数就需要该头文件,这是最基本的头文件,必须要调用。

1
#include <stdio.h>

return和exit

  exit 是强制结束运行的程序,清理进程。return 是返回函数,返回设定的参数,如果是在主函数里使用,返回值将给 exit。

打印

  打印不同的类型的值,符号是不同的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>

//主函数
int main()
{
//有符号整型
signed int a = -1;
//无符号整型
unsigned int b = -1;
printf("有符号整型:%d,无符号整型:%u\n", a, b);
//浮点型
double c = 20;
//字符型
char d = 'a';
printf("浮点型:%lf,字符型:%c\n", c, d);
return 0;
}

点击测试代码

不要使用该方法

  一行一行地打印,不要每次只打印几个字符。这样会拖慢整个运行效率,占用资源,并可能出现故障。禁止使用以下方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>

//主函数
int main()
{
int a = 0;
int n = 10;
printf("数组下标为:[");
for (int i = 0; i < n; i = i + 1)
{
if (i == n - 1)
{
printf("%d", a + i);
}
else
{
printf("%d, ", a + i);
}
}
printf("]\n");

return 0;
}

正确的方法是转化为字符串,然后打印:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <stdio.h>

//主函数
int main()
{
int a = 0;
int n = 10;
char str[100] = "数组下标为:[";
char temp[20] = { '\0' };
for (int i = 0; i < n; i = i + 1)
{
if (i == n - 1)
{
sprintf(temp, "%d", a + i);
}
else
{
sprintf(temp, "%d, ", a + i);
}
strcat(str, temp);
}
strcat(str, "]");
puts(str);

return 0;
}

点击测试代码

字符和字符串

  字符变量是由 ASCII 码对应的二进制数存在内存里的。ASCII 码可以表示基础的符号、数字和字母,占一个字节;汉字的编码占两个字节。字符串就是字符数组,字符串结尾含一个结束符。

头文件

  操作字符串使用的库函数为:

1
#include <string.h>

这是必须添加的。

指针

易错点1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>

//主函数
int main()
{
signed int arry[] = { 0, 1, 2, 3, 4, 5 };
signed int* p;
p = arry;
//打印第一个和第二个元素
//错误写法
// printf("数组下标为:%u %u\n", *ans, *ans + 1);
//正确写法
printf("数组下标为:%u %u\n", *ans, *(ans + 1));
return 0;
}

点击测试代码

易错点2

  初始化两个指针容易出现错误,导致第二个不是指针而是变量。

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>

//主函数
int main()
{
//错误写法
// signed int* p = NULL, q = NULL;
//正确写法
signed int* p = NULL,* q = NULL;
return 0;
}

点击测试代码

数组和指针

等价关系

  变量和数组是等价的。但是还是有细微区别。

  考虑一种情况:

数学符号 代码变量 说明
\(A\) signed int A[] = { 1, 2, 3, 4, 5 } 给定矩阵
\(N_A\) unsigned int N_A 元素个数(矩阵计算)
- signed int* p = A 矩阵指针
\(N_p\) unsigned int N_p 元素个数(指针计算)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <stdio.h>

int main()
{
signed int A[] = { 1, 2, 3, 4, 5 };

//元素个数计算
//矩阵法
unsigned int N_A = sizeof(A) / sizeof(A[0]);
//或者将 sizeof(A[0]) 写成 sizeof(signed int),与数组元素变量定义保持一致即可
printf("矩阵计算的元素个数为: %d\n", N_A);

//指针法
signed int* p = A;
//下面一行是错误的计算方法,因为用指针表示后,*p 指向数组当前元素,计算指针的长度就是当前元素的长度而不是数组的长度。
//signed int N_p = sizeof(*p) / sizeof(signed int);
//==========下面的方法也是错误的==========
//对于指针指向的数组元素超出最后一个时,该地址内的值是随机的。只可能在像字符串数组中含结束符号的元素数组中使用。
/*unsigned int N_p = 0;
while (*p != NULL) {
p++;
N_p = N_p + 1;
}
printf("指针计算的元素个数为: %d\n", N_p);*/
//========================================
//总结:指针法是无效的,这里就充分地看出了数组和指针地区别
//正确地做法是用数组计算元素个数,作为参数进行传递
}

点击测试代码

符号类型

  数组和指针本身都是无符号整型的。而定义数组时定义的类型是指定元素的类型。同理定义指针的类型是定义指针指向的地址内值的类型。

1
2
3
4
5
6
7
8
9
10
#include <stdio.h>

//主函数
int main()
{
signed int C[2] = { -1,2 };
unsigned int* p = C;
printf("数组显示第一个元素为: %d,指针显示第一个元素为: %d\n", C[0], *p);
return 0;
}

点击测试代码

上面定义的数组是有符号整型,指针是无符号整型,指针指向的内存地址内的值不发生改变,但是指针无符号是没有负数的,所有都会显示一个正数。

数组函数

  数组不能作为函数变量返回,但是可以返回数组的指针。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>

//声明
unsigned int* Array(unsigned int a, signed int b);

//主函数
int main()
{
//输出
unsigned int* ans;
ans = Array(nums, n, target);
printf("矩阵计算的元素个数为: %d\n", ans);

return 0;
}

//函数
unsigned int* Array(unsigned int a, signed int b)
{
//返回数组下标
signed int C[2] = { i,j };
return C;
}

点击测试代码