1.一维数组
#include <stdio.h>
//int a[10]; //未初始化的全局变量是0
int main()
{
#if 0
int a[10]; //定义有10个整型元素的数组,在内存里面连续存储
//int a[0]; //错误
int k;
//int b[k] = {0}; //数组的长度一定是确定的
#endif
//数组的初始化操作
//int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; //对所有元素初始化
//int a[10]; //没有初始化,未初始化的局部变量是垃圾值
//int a[10] = {1, 2, 3}; //对部分元素初始化,没有初始化的元素变成0
//int a[] = {1, 2, 3, 4, 5, 6 ,8, 8}; //可以不指定数组长度,但是一定要初始化
int a[10] = {0}; //所有元素初始化成0
//printf("%d\n", a); //不能直接输出整型数组
int i;
for (i = 0; i < sizeof(a) / sizeof(int); i++)
{
printf("%d ", a[i]);
}
printf("\n");
printf("%p\n", &a[0]);
printf("%p\n", a); //a表示数组首元素地址,和&a[0]意义一样
printf("%p\n", &a); //&a表示数组的地址
printf("*********\n");
printf("%p\n", &a[0] + 1);
printf("%p\n", a + 1);
printf("%p\n", &a + 1);
return 0;
}
2.二维数组
#include <stdio.h>
int main()
{
int i, j;
//int a[3][4]; //三行四列的二维数组
//int a[3][4] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; //对所有元素初始化
//int a[3][4] = {1, 2, 3, 4, 5}; //对部分元素初始化
//int a[][4] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
int a[3][4] = {0}; //整个数组初始化成0
for (i = 0; i < 3; i++) //行循环
{
for (j = 0; j < 4; j++) //列循环
{
printf("%d ", a[i][j]);
}
printf("\n"); //每行结束打印换行
}
printf("%p\n", &a[0][0]); //第一个元素的地址
printf("%p\n", a); //数组名
printf("%p\n", &a);
printf("%p\n", a[0]);
printf("%p\n", &a[0]);
printf("*************************\n");
printf("%p\n", &a[0][0] + 1); //第一个元素的地址,单位是一个元素,四个字节
printf("%p\n", a + 1); //数组名,数组首行地址,单位是一行
printf("%p\n", &a + 1); //数组的地址,单位是一个数组
printf("%p\n", a[0] + 1); //数组首行首元素地址,单位是一个元素
printf("%p\n", &a[0] + 1); //数组首行地址
/*
&a 数组地址
*(&a) 数组首行地址
a 数组首行地址
*a 数组首行元素地址
*/
return 0;
}
3.字符数组
#include <stdio.h>
int main()
{
int i;
//char a[10] = {'h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd'};
char b[15] = "helloworld";
/*char c[15];
c = "helloworld";*/
/*for (i = 0; i < 10; i++)
{
printf("%c", a[i]);
}
printf("\n");*/
printf("%s\n", b); //遇到'\0'结束
return 0;
}
4.字符串处理函数
#include <stdio.h>
#include <string.h>
int main()
{
char a[32] = {0}; //初始化字符数组 char a[32] = {'\0'};
char b[32] = "hellwoorld";
char c[32] = "123451234512345";
/*char d[32]; //d是数组名 是数组首元素低地址 是常指针
d = "helloworld";
d[32] = "helloworld";*/
//strcpy(a, b); //字符串拷贝函数,把数组b中的字符串拷贝到数组a中
//strcpy(c, b); //包括'\0',所以是全部覆盖
//strcpy(a, "helloworld");
//printf("%s\n", a);
//printf("%s\n", c);
//strcat(b, c); //字符串连接函数 把字符串c连接到字符串b后面
//strcat(b, "111111");
//strcat("11111", b); //错误
//printf("%s\n", b);
if (strcmp(b, c) > 0) //字符串比较函数 返回值 b>c 返回值大于0, b==c 返回值等于0 b<c 返回值小于0
{
printf("b > c\n");
}
if (strcmp(b, "helloworld") > 0)
{
printf("b > hello\n");
}
return 0;
}
5.自定义函数
#include <stdio.h>
void swap(int *x, int *y); //函数声明,如果函数定义 在 函数调用 的下面
void print() //函数类型void 表示没有返回值 没有形参
{
printf("helloworld!\n"); //函数体
}
int add(int x, int y) //x和y 形参(形式参数) 实参和形参个数相同、类型相同、顺序相同、名字可以不同
{ //2、给形参分配空间(栈空间) 3、传参(值传递、地址传递)
//return x + y;
int sum; //4、执行函数体
sum = x + y;
return sum; //返回结果 //5、返回
} //6、释放空间(栈空间)!!!!!
int main()
{
int a = 1, b = 2;
int result;
print(); //1、通过函数名找到函数入口地址
result = add(a, b); //a和b 实参(实际参数) 实参不要加类型
printf("%d\n", result);
printf("%d\n", add(a, b));
printf("%p\n", add); //函数名也是地址
swap(&a, &b); //当涉及修改实参值得时候,需要传地址
printf("a = %d b = %d\n", a, b);
return 0;
}
void swap(int *x, int *y)
{
int tmp = *x;
*x = *y;
*y = tmp;
}
6.宏函数
#include <stdio.h>
#define OUT printf("helloworld\n") //无参宏函数
#define P(s) printf("%s\n", s) //有参宏函数
#define SQR(x) (x) * (x) //宏函数只是简单的替换,注意优先级
/*
宏函数的优点:
1、节省空间(不需要给形参分配空间)
2、执行效率高(不需要根据地址找到函数的入口)
宏函数的缺点:
1、编译效率低(第一步预处理需要替换)
2、不安全,只是简单的替换,没有语法检查
*/
int main()
{
int a = 1, b = 2;
OUT;
P("12345");
printf("%d\n", SQR(a + b)); //1 + 2 * 1 + 2
return 0;
}