内容简介:每个标准库函数都会被声明在一个或多个标准头(standard header)中。每个标准头都包含一组相关的函数声明、宏和类型定义。例如,数学函数声明在头文件 math.h 中。标准头也称之为头文件(header file)
每个标准库函数都会被声明在一个或多个标准头(standard header)中。
每个标准头都包含一组相关的函数声明、宏和类型定义。例如,数学函数声明在头文件 math.h 中。标准头也称之为头文件(header file)
C 程序只会在两种运行环境中执行:宿主(hosted)环境或独立(freestanding)环境
vs上是宿主的,独立的我猜是写入硬件吧,估计使用的库也少。
发现C中的printf打印字符串,对类型必须 必须正确 ,不存在C#的隐式转换。比如输出的一个数字,不用ToString(),C中的字符串是%s,数字%d 浮点%f
标准库的函数不一定确保可重入(reentrant)。也就是说,在一个进程中两次调用同一个函数并行执行可能是不安全的行为。之所以制定该规则,其中一个原因是:部分标准函数会使用和修改同一个静态变量或线程变量。
因此,你不能在信号处理进程(signal handling rountine)中调用标准库函数。信号是异步的,也就是说,程序可能在任何时候收到信号,甚至是正在执行标准库函数时。当发生这种情况时,如果信号处理器再调用的标准函数与正在执行的是同一个,那么该函数则必须是可重入的。
线程安全(thread-safe):可以“同时”被几个线程安全地执行
如果头文件的定义的函数名 与内置的一些函数重名,可以
#undef 取消
把名称放在括号内,也可以调用函数而非宏:
#include <ctype.h> /* ... */ c = (toupper)(c) // 调用函数toupper()
你可以忽略包含宏定义的头文件,直接在源代码文件中明确声明该函数:
extern int toupper(int); /* ... */ c = toupper(c) // 调用函数toupper()
我在C#中经常_XXX,下划线开头代表临时变量,c中不能。
不能_a_形式标识符作为函数名或全局变量名,但是可以作为参数。局部变量和标签名称。结构成员和联合成员也可以使用下划线开头的名称作为标识符,但是第二个字符不可以是下划线或者大写字母.
在所包含的头文件中定义的所有宏标识符,都是被保留的。
(文件名也有影响)在标准头文件中被声明为文件的标识符,在它们自身命名空间范围内,是被保留的。一旦在源文件中包含一个头文件,在同一个命名空间中,不能将在该头文件中声明为文件的标识符用作其他目的,或作为宏名称。
====================www.ayjs.net 杨洋 wpfui.com ayui ay aaronyang=======请不要转载谢谢了。=========
printf输出
从输出结果可以看出:如果是小写的x,输出的字母就是小写的;如果是大写的X,输出的字母就是大写的;如果加一个#,就以标准的十六进制形式输出
特殊符号,用双符号 就可以转义 输出。
输入个值
int i;
scanf("%d", &i); //&i 表示变量 i 的地址,&是取地址符
printf("i = %d\n", i);
类似C#的Console.Read();
类似 java 的
Scanner in = new Scanner(System.in);
int a = in.nextInt();
综上所述,scanf 语句的意思就是:从键盘上输入字符 123,然后%d将这三个字符转化成十进制数 123,最后通过“取地址 i”找到变量 i 的地址,再将数字 123 放到以变量 i 的地址为地址的变量中,即变量 i 中,所以最终的输出结果就是i=123。
scanf第一个参数不要加 非输出控制符,比如\n
输入2个值
int i, j;
printf("请输入两个值,中间以空格分隔:");
scanf("%d%d", &i, &j);
printf("i = %d, j = %d\n", i, j);
运算符,除了C#的,(其实C#也有这个)
有个* 取值运算符 *指针变量
&取地址运算符 &变量名
语言类型:
基本类型
标准整数类型,以及扩充的整数类型
实数浮点类型,以及复数浮点类型
枚举类型
void类型
派生类型
指针类型
数组类型
结构类型
联合类型
函数类型
基本类型和枚举类型,统称算术类型(arithmetic type)。算术类型和指针类型,统称为标量类型(scalar type)。数组类型和结构类型被统称为聚合类型(aggregate type)。联合类型(union type)不被认为是聚合类型,因为在任一时刻下,联合中只有一个成员可以具有值
由外部定义的数组变量就是一个不完整类型:extern float fArr[]; // 外部声明
标准库的头文件针对特定用途定义了很多整数类型,例如用来显示宽字符的 wchar_t 类型。这些类型是 typedef 名称,它们是标准整数类型的同义词。
类型 ptrdiff_t、size_t 和 wchar_t 定义在头文件 stddef.h 中(以及其他头文件中);类型 char16_t 和 char32_t 定义在头文件 uchar.h 中。为了特殊需要,指定位长度的整数类型(带符号和无符号变量)定义在头文件 stdint.h 中。
此外,头文件 stdint.h 也为标准库中的所有整数类型可显示的最大值与最小值定义了宏。例如,SIZE_MAX 等于可以在 size_t 类型变量中存储的最大值。
void讲解:
没有返回值的函数,其类型为 void。例如,标准库函数 perror() 被声明为以下原型:
void perror( const char * );
下面是另一个函数原型的声明,参数列表中的关键字 void 表示该函数没有参数:
FILE *tmpfile( void );
【在C#中直接不写了。。。。】
mpfile("name.tmp"),则编译器会报错
还可以用于类型表达式、
void 类型表达式指的是没有值的表达式。例如,调用一个没有返回值的函数,就是一种 void 类型表达式:
char filename[] = "memo.txt";
if ( fopen( filename, "r") == NULL )
perror( filename ); // void表达式
//void 类型表达式指的是没有值的表达式。例如,调用一个没有返回值的函数,就是一种 void 类型表达式:
char filename[] = "memo.txt";
if (fopen(filename, "r") == NULL)
perror(filename); // void表达式
//类型转换(cast)运算(void)表达式显式地将表达式的返回值丢弃,例如,如下代码丢弃了函数返回值:
(void)printf("I don't need this function's return value!\n");
指向void的指针
一个 void* 类型的指针代表了对象的地址,但没有该对象的类型信息。这种“无数据类型”的指针主要用于声明函数,让函数可使用各种类型的指针参数,或者返回一个“多用途”的指针。例如,标准内存管理函数:
void *malloc( size_t size );
void *realloc( void *ptr, size_t size );
void free( void *ptr );
如下例所示,可将一个 void 指针值赋值给另一个对象指针类型,反之亦可,这都不需要进行显式的类型转换。
#include <stdio.h>
#include <time.h>
#include <stdlib.h> // 提供以下函数的原型
// void srand( unsigned int seed );
// int rand( void );
// void *malloc( size_t size );
// void free( void *ptr );
// void exit( int status };
enum { ARR_LEN = 100 };
int main ()
{
int i, *pNumbers = malloc(ARR_LEN * sizeof(int)); //获得相同的存储空间
if( pNumbers == NULL )
{
fprintf(stderr,"Insufficient memory.\n");
exit(1);
}
srand( (unsigned)time(NULL ); // 初始化随机数产生器
for ( i=0; i < ARR_LEN; ++i )
pNumbers[i] = rand() % 10000; // 存储一些随机数
printf("\n%d random numbers between 0 and 0000:\n", ARR_LEN);
for ( i=0; i< ARR_LEN; ++i ) // 循环输出
{
printf("%6d",pNumbers[i]); // 每次循环输出一个数字
if ( i % 10 == 9) putchar( '\n'); // 每10个数字换一行
}
free( pNumbers ); // 释放存储空间
return 0;
}
自动类型转换
强制类型转换
int total;
total=(int)10.9+(int)12.7+(int)11.8;
输出33
而
int total=10.9+12.7+11.8;
输出35 自动转换的。
10.9+12.7+11.8=35.4 为双精度浮点型,而左值 total 类型为整型,将 35.4 自动转换为整数 35
声明一个方法使用
当方法返回值是void ,顶部必须还要像C#的委托那样定义个方法签名那种,才能调用。。。
#include <stdio.h>
void count();
int main(void)
{
int i = 0;
for (i = 0; i <= 5; i++)
{
count();
}
system("pause");
return 0;
}
void count()
{
/*声明一个静态局部变量*/
static num = 0;
num++;
printf("%d\n", num);
}
还有个static知识点
在该代码中,我们通过在 count() 函数里声明一个静态局部变量 num 来作为计数器。因为静态局部变量是在编译时赋初值的,且只赋初值一次,在程序运行时它已有初值。以后在每次调用函数时就不再重新赋初值,而是保留上次函数调用结束时的值。这样,count() 函数每次被调用的时候,静态局部变量 num 就会保持上一次调用的值,然后再执行自增运算,这样就实现了计数功能。同时,它又避免了使用全局变量。
C#的static不能这么用。。
在静态数据区,内存中所有的字节默认值都是 0x00。静态变量与全局变量也一样,它们都存储在静态数据区中,因此其变量的值默认也为 0。演示示例如下所示。
#include <stdio.h>
static int g_x;
int g_y;
int main(void)
{
static int x;
printf("g_x:%d\ng_y:%d\nx:%d",g_x,g_y,x);
return 0;
}
====================www.ayjs.net 杨洋 wpfui.com ayui ay aaronyang=======请不要转载谢谢了。=========
_Generic C11标准 泛型
反正我在vs2017没跑好下面例子
支持轻量级的泛型编程设计
#include <stdio.h>
#include <string.h>
#include <stddef.h>
#include <stdint.h>
#define getTypeName(x) _Generic((x),_Bool:"_Bool",\
char: "char", \
signed char: "signed char", \
unsigned char: "unsigned char", \
short int: "short int", \
unsigned short int: "unsigned short int", \
int: "int", \
unsigned int: "unsigned int", \
long int: "long int", \
unsigned long int: "unsigned long int", \
long long int: "long long int", \
unsigned long long int: "unsigned long long int", \
float: "float", \
double: "double", \
long double: "long double", \
char *: "pointer to char", \
void *: "pointer to void", \
int *: "pointer to int",\
default: "other")
int main(void)
{
char c = 'a';
size_t s;
ptrdiff_t p;
intmax_t i;
int arr[3] = { 0 };
printf("s is '%s'\n", getTypeName(s));
printf("p is '%s'\n", getTypeName(p));
printf("i is '%s'\n", getTypeName(i));
printf("c is '%s'\n", getTypeName(c));
printf("arr is '%s'\n", getTypeName(arr));
printf("0x7FFFFFFF is '%s'\n", getTypeName(0x7FFFFFFF));
printf("0xFFFFFFFF is '%s'\n", getTypeName(0xFFFFFFFF));
printf("0x7FFFFFFFU is '%s'\n", getTypeName(0x7FFFFFFFU));
return 0;
}
extern
include <stdio.h>
int max(int x,int y);
int main(void)
{
int result;
/*外部变量声明*/
extern int g_X;
extern int g_Y;
result = max(g_X,g_Y);
printf("the max value is %d\n",result);
return 0;
}
/*定义两个全局变量*/
int g_X = 10;
int g_Y = 20;
int max(int x, int y)
{
return (x>y ? x : y);
}
代码中,全局变量 g_X 与 g_Y 是在 main 函数之后声明的,因此它的作用范围不在 main 函数中。如果我们需要在 main 函数中调用它们,就必须使用 extern 来对变量 g_X 与 g_Y 作“外部变量声明”,以扩展全局变量的作用域。也就是说,如果在变量定义之前要使用该变量,则应在使用之前加 extern 声明变量,使作用域扩展到从声明开始到本文件结束。
如果整个工程由多个源文件组成,在一个源文件中想引用另外一个源文件中已经定义的外部变量,同样只需在引用变量的文件中用 extern 关键字加以声明即可。下面就来看一个多文件的示例:
/****max.c****/
#include <stdio.h>
/*外部变量声明*/
extern int g_X ;
extern int g_Y ;
int max()
{
return (g_X > g_Y ? g_X : g_Y);
}
/***main.c****/
#include <stdio.h>
/*定义两个全局变量*/
int g_X=10;
int g_Y=20;
int max();
int main(void)
{
int result;
result = max();
printf("the max value is %d\n",result);
return 0;
}
C中有一些位运算符,C#也有我很少用,两个都一样的。
C的点运算符
struct Article { long number; // 物品编号
char name[32]; // 物品名字
long price; // 物品单价(精确到美分)
/* ... */
};
struct Article sw = { 102030L, "Heroes", 5995L };
sw.price = 4995L; // 将价格改为49.95
二元运算符 . 和 -> 常常被称为点运算符(dot operator)和箭头运算符(arrow operator),借助于这两个运算符,可以选择结构或联合中的成员。
点运算结果的类型,与所选择成员的类型是一样的。
运算符 -> 也可用于选择结构或联合的成员,但是箭头运算符的左操作数必须是一个指针,它指向一个结构或联合类型。右操作数是该结构或联合成员的名字。例 2 展示了运算符->的用法,同样使用例 1 所定义的结构 Article。
下面我写了一段代码,注释都有说明,这些 东西在C很重要
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
struct Article {
long number; // 物品编号
char name[32]; // 物品名字
long price; // 物品单价(精确到美分)
/* ... */
};
//struct Article getArticle(); // 函数原型
int main(void)
{
struct Article sw = { 102030L, "Heroes", 5995L };
printf("name: %s\n", sw.name);
struct Article *pArticle = &sw, // 一个指向struct Article的指针
const *pcArticle = &sw; // 一个指向struct Article的只读指针
++(pArticle->number); // 增加编号
if (pcArticle->number == 102031L)
{
// 正确:获取只读指针,连pcArticle.number值也变了
printf("正确 %Id \n",pcArticle->number); //102031L 引用的
}
//转换 p->m 等效于(*p.m
printf("正确转换 %Id \n", (*pcArticle).number);
//x.m 等效于(&x)->m
printf("正确转换2 %Id \n", (&sw)->number);
//优先级 ++p->m 等同于 ++(p->m)
//p->m++ 等同于(p->m)++
// *p.m 等效于 *(p.m)
//创建一个数组,10个 article
struct Article arrArticle[10];
//一个数组名称,本例中的 arrArticle,是一个指向第一个数组元素的常量指针
arrArticle[2].price = 990L; // 设置数组元素arrArticle[2]的成员price
arrArticle->number = 10100L; // 设置数组元素arrArticle[0]的成员number
//所以 arrArticle->number 指向第一个数组元素的成员 number。简单地说,对于任一的索引值 i,下面 3 个表达式是等价的:
//arrArticle[i].number
//(arrArticle + i)->number
//(*(arrArticle + i)).number
//它们都指向数组中索引值为 i 的元素的成员 number。
arrArticle->name[1] = 'a';
printf("%c", arrArticle
->name[1]
);
//pcArticle->price += 50; // 错误:不能使用限定符const的指针来修改对象
system("pause");
return 0;
}
getchar()和scan_f 的例子,控制台输入
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int main(void)
{
int a;
char ch;
while (1)
{
printf("请输入一个数字:");
scanf_s("%d", &a);
printf("a = %d\n", a);
printf("您想继续吗(Y/N):");
getchar(); /*用getchar吸收回车, 简单、方便、好用, 都不需要定义变量用来存储获取的回车符*/
ch = getchar(); //用getchar从缓冲区中读取一个字符赋给字符变量ch
if (('Y' == ch) || ('y' == ch))
{
}
else
{
break; // 跳出本层循环体
}
}
system("pause");
return 0;
}
还有fflush替代getchar(),但是 fflush 有一个问题,就是可移植性。并不是所有的编译器都支持 fflush,比如 gcc 就不支持。那么此时怎么办?还是用 getchar()。
fflush(stdin);
//while (getchar() != '\n');
使用goto跳到书签,变量名: 冒号
#include<stdio.h>
int main (void){
int n;
pos_1:
printf("请输入一个正整数:");
scanf("%d",&n);
if(n<0)
{
printf("输入错误!\n");
goto pos_1;
}
printf("成功输入正整数:%d\n",n);
return 0;
}
这个setjump和longjump 不看了。书签是当前方法 内的,方法外定义用这两个
int setjmp(jmp_buf env);
void longjmp(jmp_buf env, int value);
示例,
#include <stdio.h>
#include <setjmp.h>
jmp_buf buf;
void F2(void)
{
printf("F2()\n");
longjmp(buf,1);
}
void F1(void)
{
F2();
printf("F1()\n");
}
int main(void)
{
int jmpret = setjmp(buf);
if(!jmpret)
{
F1();
}
else
{
printf("继续执行main\n");
}
return 0;
}
F2()
继续执行main
我看不懂。。,
推荐您阅读更多有关于“C,”的文章
以上所述就是小编给大家介绍的《写给自己的用VS2017学C语言[2]》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
PHP and MySQL Web Development
Luke Welling、Laura Thomson / Sams / July 25, 2007 / $49.99
Book Description PHP and MySQL Web Development teaches you to develop dynamic, secure, commerical Web sites. Using the same accessible, popular teaching style of the three previous editions, this b......一起来看看 《PHP and MySQL Web Development》 这本书的介绍吧!