C 语言常用小点
1. 数组与指针
数组使用
二维数组
int ** arr;
三维数组
int *** arr;
void * 可以任意转换成int * ..... 任意指针
遍历和指针
int arr[] = {1,2,3};
int i=0;
for (i = 0; i < sizeof(arr) / sizeof(int); ++i) {
printf("%d\n",*(arr+i));
}
正常情况下
c语言常量不能修改,但是可以通过指针修改
const int num = 100;
int *pnum = #
*pnum = 10000;
2. 函数和指针
指针函数
void add (int num1,int num2){
printf("num1+num2=%d ",num1+num2);
}
void mins(int num1,int num2){
printf("num1-num2=%d ",num1-num2);
}
void operate(*method(int,int),int num1,num2){
method(num1,num2);
}
函数回调
void callBackMethod(char * file_name,int current,int progress){
printf("%s的图片压缩进度%d/%d\n",file_name,current,progress);
}
void compress(char * filename,void(* callBackP)(char *,int,int)){
callBackP(filename,50,100);
}
调用
void (* call)(char *,int,int);
call = callBackMethod;
compress("david.png",call);
3. 内存模式
全局区,
全局&静态&常量:全局(global)变量,静态(static)变量,各种常量(字符串字面量,const修饰的量)
代码区,
你写的代码,各种函数(包括类成员函数)
栈,
局部变量&函数参数:在函数内声明的变量(包括main函数)
堆,
使用new,malloc,colloc等关键字手动开辟的内存
磁盘,寄存器
4. 申请内存函数区别
栈区
局部变量&函数参数:在函数内声明的变量(包括main函数)
int arr[(int) (1.5 * 1024 * 1024)];
注意栈区大小有限制比较小,根据系统不同不同
堆区
使用new,malloc,colloc等关键字手动开辟的内存
windows 给编译器空间比较大,80% 大概,看实际情况
malloc:
堆中申请内存,一般情况,配合memset 对内存初始化
alloca:
栈中申请内存,不需要师范
realloc
扩容,重置指针指向内存大小,堆
calloc
malloc + memset,堆
静态分配
void foo(){
int arr[5];
...
}
main函数进栈,调用foo,foo函数进栈,foo执行完毕弹出栈,释放arr[5] 的20 空间
动态分配
char * str = malloc(100)... free(str)
void malloctest(){
int * arr = malloc(10);
printf("arr 栈%p,堆,%p\n",&arr,arr);
free(arr);
arr = NULL;
printf("2222arr 栈%p,堆,%p\n",&arr,arr);
}
5. inline的用法和解释
参见C++ 常用小点
6. 友元函数
参见C++ 常用小点
7. 频率比较高的函数
C语言速查
srand 随机数
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
int main(void)
{
int i;
time_t t;
srand((unsigned) time(&t));
printf("Ten random numbers from 0 to 99\n\n");
for(i=0; i<10; i++)
printf("%d\n", rand() % 100);
return 0;
}
strcpy 拷贝函数
#include <stdio.h>
#include <string.h>
int main(void)
{
char string[10];
char *str1 = "abcdefghi";
strcpy(string, str1);
printf("%s\n", string);
return 0;
}
sleep
#include <dos.h>
#include <stdio.h>
int main(void)
{
int i;
for (i=1; i<5; i++)
{
printf("Sleeping for %d seconds\n", i);
sleep(i);
}
return 0;
}
sticmp
strcmpi
strstr
atoi
查看c文档,小白级别
8. 字符串
char * str = "David";
char str[] = {'D','a','v','i','d','\0'}
注意‘\0’结尾
str[2] = 'z' 只能修改str[] 他是栈区
- str 不行,因为他是全局静态区,不能更改
C语言 字符串截取的几个思路
void substr(char *result, char *str, int start, int end) {
char *temp = str;
int count = 0;
while (*temp) {
temp++;
count++;
if (count >= start && count <= end) {
*result = *temp;
result++;
}
}
}
void substr2(char *result, char *str, int start, int end) {
char *temp = str;
// 截取字符串,截取多少用多少
char resultArr[end - start];
int count = 0;
int i;
for (i = start; i < end; ++i) {
resultArr[count] = *(temp + i);
count++;
}
// *result = resultArr;//x 错误一级指针指向容器,因为容器结束方法会栈回收
strcpy(result, resultArr);//1. copy字符串
}
void substr2_2(char **result, char *str, int start, int end) {
char *temp = str;
// 截取字符串,截取多少用多少
char resultArr[end - start];
int count = 0;
int i;
for (i = start; i < end; ++i) {
resultArr[count] = *(temp + i);
count++;
}
strcpy(*result, resultArr);//1. copy字符串
}
void substr3(char **result, char *str, int start, int end) {
char *temp = str;
// 截取字符串,截取多少用多少
char *resultArr = malloc(end - start);
int count = 0;
int i;
for (i = start; i < end; ++i) {
resultArr[count] = *(temp + i);
count++;
}
*result = resultArr;
}
void substr4(char *result, char *str, int start, int end) {
int i;
for (i = start; i < end; ++i) {
*(result++) = *(str + i);
}
}
void substr5(char **result, char *str, int start, int end) {
strncpy(*result, str+start, end-start);
}
int main() {
char *str = "David is good is better man ! Alex eat shit!";
char *result;
// substr(result,str,2,5);
// substr2(result, str, 2, 5);
// substr3(&result, str, 2, 5);
// free(result);
// substr2_2(&result, str, 2, 5);
// substr4(result, str, 2, 5);
substr5(&result, str, 2,5);
printf("result === %s", result);
}
9. 用指针获取长度,有的时候传递数组sizeof不灵
int getLen(char * str){
int count=0;
while(*str){
str++;
count++;
}
return count;
}
int getLen2(int intarr[]){
int len = sizeof(intarr) / sizeof(int);
printf("getLen2 len:%d\n",len);
}
int getLen3(int * intarr){
int len = sizeof(intarr) / sizeof(int);
printf("getLen2 len:%d\n",len);
}
int getLen4(int * intarr){
int count=0;
while(*intarr){
intarr++;
count++;
}
printf("getLen2 len:%d\n",count);
return count;
}
int main(){
char str[] = {'A','B','C','\0'};
int len = getLen(str);
printf("length str:%d\n" ,len);
int arr[]={1,2,3,4,5,6,7};
getLen2(arr);
getLen3(arr);
getLen4(arr);
}
10 结构体
struct Dog {
char name[10];
int age;
char sex;
};
struct Person {
char *name;
int age;
char sex;
} ppp = {"David", 33, 'M'};
struct Study {
char *studyContent;
};
struct Student {
char *name;
int age;
char sex;
struct Study study;
struct Wan {
char *wanContent;
} wan;
};
struct Cat{
char name[10];
int age;
};
int main() {
struct Dog dog;
strcpy(dog.name, "xiao miao");
dog.sex = 'w';
printf("name %s,%c\n", dog.name, dog.sex);
printf("name %s,%c,%d\n", ppp.name, ppp.sex, ppp.age);
struct Student student = {
"David", 'M', 33,
{
"C++"
}, {
"王者荣耀"
}
};
Struct Student *student1 = &student;
student1->age = 3;
struct Cat * cat = malloc(sizeof(struct Cat));
strcpy(cat->name,"Cat Cat");
free(cat);
cat = NULL;
return 0;
}
struct 兼容
struct Worker_{
char name[10];
int age;
char sex;
};
typedef struct Worker_ Worker_;
typedef struct Worker_ * Worker;
//=======
typdef struct Worker_{
char name[10];
int age;
char sex;
} worker;
`枚举`类似enum的兼容
typedef enum CommenType{
TEXT = 10,
TEXT_IMAGE,
IMAGE
}CommenType;
int main() {
Worker worker;
return 0;
}
很多源码,大量使用typedef 别名,原因是为了平台的兼容问题。
结构体定义与使用
struct Book1{
char title[10];
char author[10];
int id;
} book = {.title="c lang",.author="av",.id=1};
struct Book book1;
strcpy(book1.title,"c++ lang");
strcpy(book1.author,"david");
book1.id = 2;
-> 指针使用
struct Book *p;
p = &book1;
printf("book id:%d\n",p->id);
printf("book title:%s\n",p->title);
printf("book author:%s\n",p->author);
printf("book id:%d\n",(*p).id);
printf("book title:%s\n",(*p).title);
printf("book author:%s\n",(*p).author);
Union 类似Struct
union Data{
int i;
float f;
char str[20];
} data ={.i=1,.f=1.0,.str="ddd"};
-> 占用内存方式有区别
printf("%lu",sizeof(book1));
printf("%lu",sizeof(data));
11. 文件操作读写,加解密
int main15() {
//FILE *fopen(const char * __restrict __filename, const char * __restrict __mode) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_2_0, __DARWIN_ALIAS(fopen));
//r,w,rb,rw
char *filename = "/Users/zcw/dev/c_workspace/TempC/src/cpp/DavidFile.txt";
FILE * file = fopen(filename, "r");
if(!file){
printf("文件打开失败,请检%s文件查路径",filename);
exit(0);
}
char buffer[10];
while(fgets(buffer,10,file)){
printf("%s",buffer);
}
//close
fclose(file);
return 0;
}
int main17() {
//FILE *fopen(const char * __restrict __filename, const char * __restrict __mode) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_2_0, __DARWIN_ALIAS(fopen));
//r,w,rb
char *filename = "/Users/zcw/dev/c_workspace/TempC/src/cpp/DavidFileW.txt";
FILE * file = fopen(filename, "w");
if(!file){
printf("文件打开失败,请检%s文件查路径",filename);
exit(0);
}
fputs("David Success",file);
//close
fclose(file);
return 0;
}
int main18() {
//FILE *fopen(const char * __restrict __filename, const char * __restrict __mode) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_2_0, __DARWIN_ALIAS(fopen));
//r,w,rb
char *filename = "/Users/zcw/dev/c_workspace/TempC/src/cpp/DavidFile.txt";
char *filenameCopy = "/Users/zcw/dev/c_workspace/TempC/src/cpp/DavidFileCopy.txt";
//读取二进制
FILE * file = fopen(filename, "rb");
FILE * fileW = fopen(filenameCopy,"wb");
if(!file || !fileW){
printf("文件打开失败,请检%s文件查路径",filename);
exit(0);
}
int buf[512];
int len;//每次读取长度
while((len = fread(buf, sizeof(int),
sizeof(buf)/ sizeof(int),file)) !=0){
fwrite(buf, sizeof(int), len, fileW);
fflush(fileW);
}
//close
fclose(file);
fclose(fileW);
return 0;
}
int main19(){
//FILE *fopen(const char * __restrict __filename, const char * __restrict __mode) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_2_0, __DARWIN_ALIAS(fopen));
//r,w,rb
char *filename = "/Users/zcw/dev/c_workspace/TempC/src/cpp/DavidFile.txt";
//读取二进制
FILE * file = fopen(filename, "rb");
if(!file){
printf("文件打开失败,请检%s文件查路径",filename);
exit(0);
}
// 指针挪动读取大小,SEEK_SET,SEEK_CUR,SEEK_END
fseek(file,0,SEEK_END); //file 有了更丰富的值
long file_size = ftell(file); //file 赋值记录信息
printf("%s文件的大小是%ld\n",filename,file_size);
//close
fclose(file);
return 0;
}
int main20(){
char *filename = "/Users/zcw/dev/c_workspace/TempC/src/cpp/DavidFile.txt";
char *filenameEncode = "/Users/zcw/dev/c_workspace/TempC/src/cpp/DavidFileEncode.txt";
//读取二进制
FILE * file = fopen(filename, "rb");//文件已经有了
FILE * fileEncode = fopen(filenameEncode, "wb");//创建0kb文件
if(!file || !fileEncode){
printf("文件打开失败,请检%s文件查路径",filename);
exit(0);
}
//TODO
//加密,破坏文件,解密,还原之前的样子
// 每个字节都拿出来,对每一个字节处理
// 部分加密一部分拿出来处理
// while 循环遍历取出来的10
// 10 异或 5 变成 1111
//TODO
// 解密 1111 异或 5 还原10
int c;//接受读取值,fget 返回EOF=end of file
while((c = fgetc(file)) != EOF ){
fputc(c ^ 5,fileEncode);
}
//close
fclose(file);
fclose(fileEncode);
return 0;
}
int main21(){
char *filename = "/Users/zcw/dev/c_workspace/TempC/src/cpp/DavidFileEncode.txt";
char *filenameDecode = "/Users/zcw/dev/c_workspace/TempC/src/cpp/DavidFileDecode.txt";
//读取二进制
FILE * file = fopen(filename, "rb");//文件已经有了
FILE * fileDecode = fopen(filenameDecode, "wb");//创建0kb文件
if(!file || !fileDecode){
printf("文件打开失败,请检%s文件查路径",filename);
exit(0);
}
int c;//接受读取值,fget 返回EOF=end of file
while((c = fgetc(file)) != EOF ){
fputc(c ^ 5,fileDecode);
}
//close
fclose(file);
fclose(fileDecode);
return 0;
}
int main(){
// char *filename = "/Users/zcw/dev/c_workspace/TempC/src/cpp/DavidFile.txt";
// char *filenameDecode = "/Users/zcw/dev/c_workspace/TempC/src/cpp/DavidFileEncode2.txt";
char *filename = "/Users/zcw/dev/c_workspace/TempC/src/cpp/DavidFileEncode2.txt";
char *filenameDecode = "/Users/zcw/dev/c_workspace/TempC/src/cpp/DavidFileDecode2.txt";
char * password = "123456";
//读取二进制
FILE * file = fopen(filename, "rb");//文件已经有了
FILE * fileDecode = fopen(filenameDecode, "wb");//创建0kb文件
if(!file || !fileDecode){
printf("文件打开失败,请检%s文件查路径",filename);
exit(0);
}
int c;//接受读取值,fget 返回EOF=end of file
int index = 0;
int pass_len = strlen(password);
while((c = fgetc(file)) != EOF ){
char item = password[index % pass_len];
index++;
//1 2 3 4 5 1 2 3 4 5
printf("%c\n",item);
fputc(c ^ item,fileDecode);
}
//close
fclose(file);
fclose(fileDecode);
return 0;
}