指针使用
#include <stdio.h>
{
int val_value = 10;
int *p ; //定义指针
p = &val_value;
printf("val_value 变量地址:%p\n", p);
return 0;
}
结果为:
val_value 变量地址:0x7ffeeaae08d8
什么是指针
指针也就是内存地址,指针变量是用来存放内存地址的变量。就像其他变量或常量一样,您必须在使用指针存储其他变量地址之前,对其进行声明。
- 整型的指针只能存储整型变量的指针地址。
- 所有实际数据类型,只要是C语言中有效的数据类型,对应指针的值的类型都是一样的,都是一个代表内存地址的长的十六进制数。
- 不同数据类型的指针之间唯一不同的是,指针所指向的变量或常量的数据类型不同。
- 指针需要声明。
函数指针
- 函数指针是指向函数的指针变量
- 函数指针可以像一般函数一样调用函数、传递函数。
- 函数指针也需要声明
实例:
#include <stdio.h>
int max(int x, int y)
{
return x > y ? x : y;
}
int main(void)
{
/* p 是函数指针 */
int (* p)(int, int) = & max; // &可以省略
int a, b, c, d;
printf("请输入三个数字:");
scanf("%d %d %d", & a, & b, & c);
/* 与直接调用函数等价,d = max(max(a, b), c) */
d = p(p(a, b), c);
printf("最大的数字是: %d\n", d);
return 0;
}
回调函数
函数指针变量作为某个函数的参数来使用,回调函数就是通过函数指针调用函数
举例
你到一个商店买东西,刚好你要的东西没有货,于是你在店员那里留下了你的电话,过了几天店里有货了,店员就打了你的电话,然后你接到电话后就到店里去取了货。在这个例子里,你的电话号码就叫回调函数,你把电话留给店员就叫登记回调函数,店里后来有货了叫做触发了回调关联的事件,店员给你打电话叫做调用回调函数,你到店里去取货叫做响应回调事件。
#include <stdlib.h>
#include <stdio.h>
//回调函数
void populate_array(int *array, size_t arraySize, int (*getNextValue)(void))//populate_array第三个参数是函数的指针
{
for (size_t i = 0; i< arraySize; i++)
array[i] = getNextValue();
}
//获取随机值
int getNextRandomValue()
{
return rand();
}
int main(void)
{
int myarray[10];
populate_array(myarray, 10, getNextRandomValue);
for(int i =0; i< 10 ;i++) {
printf("%d", myarray[i]);
}
printf("/n");
return 0;
}
C位域
我的理解就是,c语言中定义了一个数据类型的变量,然而这个数据类型是占4个字节,而在使用的时候一直只用了2个字节,相当于浪费了两个字节;我们可以声明这个变量的宽度,可以更好的利用内存空间和处理简单。
C typedef
C语言提供typedef关键字,可以为类型取一个新的名字。
例如:
//先定义
typedef int BOOL;
#define TRUE 1
#define FALSE 0
//后定义
BOOL bflag = TRUE;
此时BOOL为一个数据类型, TRUE和FALSE都是变量。
所以说,typedef定义了新的类型名字,define定义了新的变量名字
C语言中常把字符拷贝到字符数组中,如下
char title[20];
char BookName[] = "Boom";
strcpy(title, BookName);
输入/输出
C语言中的I/O,标准输入函数Scanf(),由键盘键入;标准输出函数printf()
- 所有的语言程序都需要包括main()函数,代码从main()开始执行。
- printf()用于格式化输出到屏幕。printf()函数在stdio.h头文件中声明
- stdio.h 是一个头文件 (标准输入输出头文件) and #include 是一个预处理命令,用来引入头文件。
当编译器遇到 printf() 函数时,如果没有找到 stdio.h 头文件,会发生编译错误。 - return 0;表示退出程序
getchar()函数从屏幕上读取一个字符,可循环读取多个 。
putchar()函数输出到屏幕上一个字符,可循环输出多个,
gets(char *s)函数从 stdin 读取一行到 s 所指向的缓冲区,直到一个终止符或 EOF。
puts(const char *s)函数把字符串 s 和一个尾随的换行符写入到 stdout。
文件读写
fopen()函数来创建一个新的文件夹或者打开一个已有的文件。这个调用会初始化类型FILE的一个对象;类型FILE包含了所有用来控制流的必要信息。
FILE *fopen( const char * filename, const char * mode);//filename 是字符串,用来命名文件,mode是访问模式
fclose()函数关闭文件
int fclose(FILE *fp)
如果成功关闭文件返回0,否则关闭文件时发生错误,函数返回EOF。
函数 fputc() 把参数 c 的字符值写入到 fp 所指向的输出流中。
int fputc(int c, FILE *fp);
函数 fputs() 把字符串 s 写入到 fp 所指向的输出流中。
int fputs(const char *s, FILE *fp)
fgetc() 函数从 fp 所指向的输入文件中读取一个字符。·
int fgetc( FILE * fp );;
函数 fgets() 从 fp 所指向的输入流中读取 n - 1 个字符。它会把读取的字符串复制到缓冲区 buf,并在最后追加一个 null 字符来终止字符串。
char *fgets( char *buf, int n, FILE *fp );
预处理器
指令 | 描述 |
---|---|
#define | 定义宏 |
#include | 包含一个源代码文件 |
#undef | 取消已定义的宏 |
#ifdef | 如果宏已经定义,则返回真 |
#ifndef | 如果宏没有定义,则返回真 |
#if | 如果给定条件为真,则编译下面代码 |
#else | #if 的替代方案 |
#elif | 如果前面的 #if 给定条件不为真,当前条件为真,则编译下面代码 |
#endif | 结束一个 #if……#else 条件编译块 |
#error | 当遇到标准错误时,输出错误消息 |
#pragma | 使用标准化方法,向编译器发布特殊的命令到编译器中 |
预处理器的命令都是以#开头
头文件
#include <file>
引用系统头文件
#include "file"
引用用户头文件
强制类型转换
- 强制类型转换运算符的优先级大于除法。
- 类型转换可以是隐式的,由编译器自动执行,也可以是显式的,通过使用强制类型转换运算符来指定。
例如:
int i = 17; char c = 'c'; int sum; //c 的ascii 值是99
sum = i+c;
printf("Value of sum : %d\n" , sum)
输出结果为: Value of sum : 116