目录
普通局部变量,普通全局变量,普通函数,静态局部变量,静态全局变量,静态函数
内存分区
大部分人都说内存分区这块了解一下就好,但是个人感觉这块是最重要的啊,C语言玩的就是内存啊.
未运行的可执行程序内存分区
bss区:未初始化的全局变量 静态变量
data区:以初始化的全局变量 静态变量
text区:二进制指令
运行中的可执行程序内存分区
堆区:由malloc ralloc calloc 定义的变量
栈区:局部变量 形参 返回值
返回值:字节数较大的返回值会在栈区,小的会在寄存器上,具体大小好像是4B,不过个人简单的认为内置类型在寄存器上,自定义类型在栈上.
全局区:
bss区:未初始化的全局变量 静态变量
data区:以初始化的全局变量 静态变量
文字常量区:字符串常量 字符常量
代码区(text区):二进制指令
普通局部变量,普通全局变量,普通函数,静态局部变量,静态全局变量,静态函数
普通局部变量
定义在{}内的普通变量
普通局部变量同名是会采用就近原则(少写非人类的代码)
不初始化时值为垃圾值.
作用区域:当前{}内有效
生命周期:
当前{}内
离开{}自动回收空间
存储区域:栈区
普通全局变量
定义在{}外的普通变量
其他文件想要使用需要声明(extern 类型 变量名)
不初始化时自动初始化为0
作用区域:当前文件内有效(其他文件想要使用需要声明)
生命周期:
当前进程(程序)
进程结束后自动回收空间
存储区域:全局区
静态局部变量
定义在{}内,前加static的变量
不初始化时自动初始化为0
作用区域:当前{}内有效
生命周期:
当前进程(程序)
进程结束后自动回收空间
存储区域:全局区
静态全局变量
定义在{}外,前加static的变量
不初始化时自动初始化为0
其他文件不能使用
作用区域:当前文件内有效
生命周期:
当前进程(程序)
进程结束后自动回收空间
存储区域:全局区
普通函数
其他文件想要使用需要加extern声明
静态函数
前加static的函数
其他文件不能使用,只在当前文件内有效.
如果非要在其他文件中使用,可以在当前文件中定义普通函数,再去调用静态函数
函数
#include <stdio.h>
void func()
{
printf("hello world\n");
}
int main(int argc,char * argv[])
{
//其实函数书写的顺序应该是 调用->声明->定义(实现) 这样写可以有效的避免代码的重复毕竟那是一件很蠢的事情
//函数名就是函数的首地址,我用的是VS没办法演示
func();
//函数指针,这个之后在说,但是指针现在也没说....
//反正意思差不多,函数名就是函数的首地址
void(*p)() = func;
p();
return 0;
}
//哦,忘记说一点,当实参传入形参的时候相当于
//形参 = 实参 赋值操作(会发生自动类型转换,创值的时候不会修改实参)
//函数位调用时形参并不会开辟空间
冒泡排序
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
//交换变量
void swap(int* num, int* num2);
//冒泡排序
void bubbleSort(int arr[], int len);
//遍历数组
void showArr(int arr[], int len);
int main(int argc,char * argv[])
{
int arr[10] = { 0 };
//以当前系统时间作为随机数种子(记得好像是这样,这个不重要)
//如果不加,每次运行得到的随机数都一样
//srand在头文件stdlib.h中
//time在头文件time.h中
srand((unsigned)time(NULL));
for (int i = 0; i < 10; ++i)
{
//初始化数组arr
//rand在头文件stdlib.h中
//rand取随机数
//rand() % 100 取[0,100) 后面 +1 表示 [1,100]
arr[i] = rand() % 100 + 1;
}
//求数组长度
int len = sizeof(arr) / sizeof(arr[0]);
showArr(arr, len);
bubbleSort(arr, len);
showArr(arr, len);
return 0;
}
//交换变量,因为值传递不会改变实参,相当于赋值操作(形参 = 实参,num = arr[0])
//指针传递的是地址,操作地址,可以改变原变量.(其实也是赋值操作,两个地址指向一个实体(int变量)) 这个文字描述实在无力啊
//总之改变变量需要指针,改变一级指针需要二级指针
void swap(int* num, int* num2)
{
//这个之前说过
*num ^= *num2;
*num2 ^= *num;
*num ^= *num2;
}
//冒泡排序
void bubbleSort(int arr[], int len)
{
//len个元素排序,需要排序len - 1次
//也可以理解成如果只有一个元素不需要排序
//其实实际上就是越界,需要从最后一个元素开始到第一个元素,或从第一个元素开始到最后一个元素
for (int i = 0; i < len - 1; ++i)
{
//一次循环排序一个,排完一次减少一个
for (int j = 0; j < len - 1 - i; ++j)
{
if (arr[j] > arr[j + 1])
{
//前一个元素大于后一个元素交换,则循环一次最大值会交换到最后一个元素
swap(&arr[j], &arr[j + 1]);
}
}
}
如果从最后一个元素开始到第一个元素,需要这么写
//for (int i = 0; i < len - 1; ++i)
//{
// //一次循环排序一个,排完一次减少一个
// for (int j = len - 1; j > i; --j)
// {
// if (arr[j] < arr[j - 1])
// {
// //如果这么写,前一个元素大于后一个元素交换,则循环一次最小值会交换到第一个元素
// swap(&arr[j], &arr[j + 1]);
// }
// }
//}
}
//遍历数组
void showArr(int arr[], int len)
{
for (int i = 0; i < len; ++i)
{
printf("%d ", arr[i]);
}
printf("\n");
}
字符串逆序
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
void stringReversed(char str[], int len);
void swap(char* ch, char* ch2);
int main(int argc,char * argv[])
{
srand((unsigned)time(NULL));
char str[10] = "";
//减1是为了存储'\0'
for (int i = 0; i < sizeof(str) - 1; ++i)
{
//初始化成小写字母 [0,26) 加97(97 ASCII码对应a)[97,122]
//发生隐式类型转换(自动类型转换)
str[i] = rand() % 26 + 97;
}
printf("%s\n",str);
stringReversed(str, strlen(str));
printf("%s\n",str);
return 0;
}
void stringReversed(char str[], int len)
{
int front = 0; //第一个元素下标
int back = len - 1; //最后一个元素下标
//相等时不需要交换,说明是中间的元素
while (back > front)
{
swap(&str[front], &str[back]);
--back;
++front;
}
}
void swap(char* ch, char* ch2)
{
*ch ^= *ch2;
*ch2 ^= *ch;
*ch ^= *ch2;
}