c != ' ' && c != '\n' && c != '\t' /* 如果c不是空白字符,该表达式为真*/
c == ' ' || c == '\n' || c == '\t' /*如果c是空白字符,该表达式为真*/
int a = 1;
float pi;
pi = 1 - a / 3;//此处的pi值为0,因为整形除以整形为整形,会溢出数字。需要至少一个数为浮点数。
printf("%f",pi);
a = a + k - 1;
if (a > 'Z')
{
a = a - 'Z' + 'A' - 1;//此处的-1及其容易漏掉,否则就头尾都没有加上
return a;
}
x = (unsigned int)x>>n | x << 32-n//移动n位
float类型为小数点位后六位,可能会出现莫名奇妙的溢出。所以当需要使用正好是小数点位后六位时,建议选择双精度浮点型。
c语言中对于下面的语句认为真(输出为ok),比较两个数时对其类型要求并不十分严格!
#include
int main()
{
float m = 2.0, n = 1.0;
int a = 2;
if (m / n == a)
printf("ok!");
return 0;
}
x = x % max + 1;
tolower(ch); // 不影响ch的值
ch = tolower(ch); // 把ch转换成小写字母
while(isspace(s[i])) i++;//跳过前导空白符
sign=(s[i]=='-') ? -1: 1;//判断符号
double val;
for(val=0;isdigit(s[i]);i++)
{
val=10*val + (s[i-'0']);
}
for(i=1,power=0.1;isdigit(s[i]);i++,power*=0.1)
{.
val+=(s[i]-'0')*power;
}
a<b?-1: a>b?1:0//a小返回-1,大返回1,相等返回0
# include
int main(void)
{
int M,N;
scanf("%d %d",&M,&N);
int a[M], b[M];
int i, j, k;
for (i=0; i<M;i++)
a[i]=i+1;
for (i=M,j=0; i>1; i--)
{
for (k=1; k<=N; k++)
if(++j>i-1) j=0;/*最后一个人报完数后,
第一个人接着报数,形成一个圈*/
b[M-i]=j? j-1: i;//与上面圈对应的操作
if(j)//与上面圈对应的操作!
for(k=--j; k<i; k++)
a[k] = a[k+1];
}
//for(i=0; j
//printf("%6d", b[i]);
printf("%d", a[0]);
return 0;
}
#include
#include
int main()
{
//定义字符串的几种方式
//字符串和字符数组的区别:最后一位是否是空字符
char names1[] = {'j', 'a', 'c', 'k', '\0'};
char names2[50] = "jack";
char * names3 = "jack";
printf("数组所占空间大小:%d\n", sizeof(names1));
printf("数组所占空间大小:%d\n", sizeof(names2));
//动态输入
printf("请输入新名称: ");
scanf("%s", names2);
printf("%s\n", names2);
return 0;
}
/*
注意:
声明存储字符串的数组时,数组大小至少比所存储的字符串多1,因为编译器会自动在
字符串常量的末尾添加空字符\0
*/
// divisors.c -- 使用嵌套if语句显示一个数的约数
#include
#include
int main(void)
{
unsigned long num; // 待测试的数
unsigned long div; // 可能的约数
bool isPrime; // 素数标记
printf("Please enter an integer for analysis; ");
printf("Enter q to quit.\n");
while (scanf("%lu", &num) == 1)
{
for (div = 2, isPrime = true; (div * div) <= num; div++)
{//上面的布尔类型isPrime可利用逗号表达式进行再次定义为真
if (num % div == 0)
{
if ((div * div) != num)
printf("%lu is divisible by %lu and %lu.\n",
num, div, num / div);
else
printf("%lu is divisible by %lu.\n",
num, div);
isPrime = false; // 该数不是素数
}
}
if (isPrime)//若程序未进入上面的if语句,就执行此if语句!
printf("%lu is prime.\n", num);
printf("Please enter another integer for analysis; ");
printf("Enter q to quit.\n");
}
printf("Bye.\n");
return 0;
}
do
{
语句;
} while(条件);
#include
int main(void){
int a;
printf("input integer number: ");
scanf("%d",&a);
switch (a){
case 1:printf("Monday\n");
case 2:printf("Tuesday\n");
case 3:printf("Wednesday\n");
case 4:printf("Thursday\n");
case 5:printf("Friday\n");
case 6:printf("Saturday\n");
case 7:printf("Sunday\n");
default:printf("error\n");
}
return 0;
}
printf("Enter an integer (q to quit):\n");
while(scanf("%lu", &number) == 1)//此处技巧性极强
{
printf("Binary equivalent:");
to_binary(number);
putchar('\n');
printf("Enter an integer (q to quit):\n");
}
#include
#include
int isprime(int n);
int main()
{
long m;
int i = 0;
scanf_s("%ld", &m);
while ((int)pow(2, i) - 1 <= m)
{
if (isprime(i) && isprime(pow(2, i) - 1))
printf("M(%d)=%d\n", i, (int)pow(2, i) - 1);
i++;
}
return 0;
}
int isprime(int n)//注意此函数是如何判断循环体是否完全执行完毕的!
{
int i;
for (i = 2; i < n; i++)
{
if (n % i == 0)
break;
}
if (i == n)
return 1;
else
return 0;
}
/***在下面Begin至End间,按原型 void diceGame(int randSeed) 定义函数***/
/********** Begin **********/
#include
void diceGame(int randSeed);
int main()
{
diceGame(10);
return 0;
}
void diceGame(int randSeed)
{
srand(randSeed);
int count = 1;
do
{
if (count > 1)
{
if (x == 7)
{
printf("Round %d: Score:7 Failed!\n", count);
break;
}
else if (x == last)
{
printf("Round %d: Score:%d Success!\n", count, x);
break;
}
else
{
printf("Round %d: Score:%d Cooutinue!\n", count, x);
continue;
}
}
//count++;若把累加器写在此处可能会出现问题(多出口循环!)
} while (1);
count++;
}
/********** End **********/
#include
int main(void)
{
int length;
scanf_s("%d", &length);
int nums[100][100];
int i, j;
/*计算杨辉三角*/
for (i = 0; i < length; i++)
{
nums[i][0] = 1;
nums[i][i] = 1;
for (j = 1; j < i; j++)
nums[i][j] = nums[i - 1][j - 1] + nums[i - 1][j];
}
/*打印输出*/
for (i = 0; i < length; i++)
{
for (j = 0; j < length - i - 1; j++)
printf(" ");
for (j = 0; j <= i; j++)
printf("%-4d", nums[i][j]);
putchar('\n');
}
return 0;
}
#include
#define swap(x,y) {(x) = (x) ^ (y); (y) = (x) ^ (y); (x) = (y) ^ (x);}
int main()
{
int x, y,z;
scanf("%d%d%d", &x,&y,&z);
if(x>y) swap(x,y);
if(x>z) swap(x,z);
if(y>z) swap(y,z);
printf("%d %d %d", x,y,z);
return 0;
}
数据类型 | 字节数 | 取值范围 |
---|---|---|
signed char | 1 | -128 ~ 127 |
unsigned char | 1 | 0 ~ 256 |
short | 2 | -32768 ~ 32767 |
int | 4 | -2147483648 ~ 2147483647 |
long | 4 | -2147483648 ~ 2147483647 |
long long | 8 | 19位数 |
float | 4 | 1.17549 * 10(-38) ~ 3.40282 * 10(38) |
if(m == n) return;
m=m^n;
n=m^n;
m=n^m;
/*用位运算实现交换m和n,使用异或*/
实参的求值顺序是未定义行为,由编译器决定。
所以一般避免使用会引起副作用的实参表达式
全局变量的的作用域属于文件范围
extern是对全局变量的引用性声明(而非定义)
存储类型一共有四种类型:auto , extern , static , register
ch = getchar(); /* 读取一个字符 */
while (ch != '\n') /* 当一行未结束时 */
{
... /* 处理字符 */
ch = getchar(); /* 获取下一个字符 */
}
例如这种替换(经典 )
while ((ch = getchar()) != '\n')
{
... /* 处理字符 */
}
#include
int mian()
{
char ch;
printf("请输入一个字符:(输入ctrl + z结束)");//输入A和'\n'会先处理A后,再直接换行
while ((ch = getchar()) != EOF)
{
if (isupper(ch))
{
ch = ch + 32;
}
putchar(ch);
}
return 0;
}
#include
int main()
{
unsigned int count=0;
char num;
int sum=0;
printf("请输入一个十进制正整数:");
for (;num = getchar(), num != '\n'; count++)//注意空语句的使用!
{
sum += num - 48;
}
printf("是%d位数,其各位数之喝是%d!", count, sum);
return 0;
}
char a;//用户输入数字3
scanf("%d", &a);
printf("%d", a); //输出值为51,为字符'3'的ASCII码!
所以scanf()函数接收数据时与定义变量时的类型一致!
#include
#include
#include
int s[10000],n,i;
int cmp(const void *a,const void *b)
{
return(*(int *)b-*(int *)a); //实现的是降序排序
}
int main()
{
// 输入想要输入的数的个数
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",&s[i]);
qsort(s,n,sizeof(s[0]),cmp);
for(i=0;i<n;i++)
printf("%d ",s[i]);
return(0);
}
s = t(t-a)(t-b)(t-c)//编译器会报错:t()不是一个函数
#define _CRT_SECURE_NO_WARNINGS
//成绩排序
#include
#include
void sorted(char* pname[], int* grade, int number);
int button;
int number;
char name[100][100];
char* pname[100];
int grade[100];
int main()
{
while (scanf("%d", &button) == 1)
{
switch (button)
{
case 0: return 0;
case 1:
{
scanf("%d", &number);
for (int i = 0; i < number; i++)
{
int a;
char tmp[100];
scanf("%s", tmp);
pname[i] = name[i];
scanf("%d", &a);
grade[i] = a;
strncpy(pname[i], tmp,100);
}
}
break;
case 2:
sorted(pname, grade, number);
break;
case 3:
{
for (int i = 0; i < number; i++)
{
printf("%s %d\n", pname[i], grade[i]);
}
}
}
}
return 0;
}
void sorted(char* pname[], int* grade, int number)
{
int a, b;
for (a = 0; a < number; a++)
{
for (b = a + 1; b < number; b++)
{
if (grade[a] < grade[b])
{
grade[a] = grade[a] ^ grade[b];
grade[b] = grade[a] ^ grade[b];
grade[a] = grade[b] ^ grade[a];
char* tmp;
tmp = pname[b];
pname[b] = pname[a];
pname[a] = tmp;
}
if (grade[a] == grade[b])
{
if (strncmp(pname[a], pname[b], 100) < 0);
else
{
grade[a] = grade[a] ^ grade[b];
grade[b] = grade[a] ^ grade[b];
grade[a] = grade[b] ^ grade[a];
char* tmp;
tmp = pname[b];
pname[b] = pname[a];
pname[a] = tmp;
}
}
}
}
}
//以下程序输出结果为 1
#define _CRT_SECURE_NO_WARNINGS
#include
#include
int main()
{
char a[] = "-100";
char b[] = "101";
int c;
c = atoi(a) + atoi(b);
printf("c = %d\n", c);
return 0;
}
解决方法
1.函数返回
将malloc得到的内存首地址通过函数的返回值返回到主函数。
#include
#include
#include
char* test()
{
char *p;
p = (char*)malloc(10 * sizeof(char));
strcpy(p, "123456789" );
return p;
}
void main()
{
char *str = NULL ;
str = test();
printf("%s\n", str);
free(str);
}
2.二级指针
将malloc得到的内存首地址通过二级指针返回到主函数。
#include
#include
#include
void test(char **p)
{
*p = (char*)malloc(10 * sizeof(char));
strcpy(*p, "123456789" );
}
void main()
{
char *str = NULL ;
test(&str);
printf("%s\n", str);
free(str);
}
常见误区
1.使用一级指针
#include
#include
#include
void test(char *p)
{
p = (char*)malloc(10 * sizeof(char));
strcpy(*p, "123456789" );
}
void main()
{
char *str = NULL ;
test(str);
printf("%s\n", str);
free(str);
}
看上去合情合理,把malloc得的地址赋给指针p,这样我们传入的str就指向申请的内存了。但事实是,str的值并没有变化。我们可以先看下方的代码。
#include
void test(char c)
{
c = 'B';
}
void main()
{
char ch = 'A' ;
test(ch);
printf("%c\n", ch);
}
调用test()后,主函数里面的ch值还是’A’,而不是’B’。这是因为在调用函数的时候,char c 事实上是被复制进函数内部的,函数内的操作不会影响到原值。
指针也是一样的道理。传入一个一级指针,只能修改它指向的数据,而不能修改它指向的地址。所以我们应该传入一个二级指针,这个指针指向一级指针。这样我们就能修改位于二级指针指向的数据,即一级指针指向的地址了。
2.二级指针未指向存在的一级指针
#include
#include
#include
void test(char **p)
{
*p = (char*)malloc(10 * sizeof(char));
strcpy(*p, "123456789" );
}
void main()
{
char **str = NULL ; //原代码:char *str = NULL;
test(str); // test(&str);
printf("%s\n", str);
free(str);
}
为什么我使用了二级指针,仍然是错误的呢?对比下正确的代码,就一目了然了。正确代码中,通过对一级指针str进行取址,得到指向str的二级指针,在子函数中就可以操作str的值了。而错误代码中,二级指针的值为NULL,这样的花子函数中操作的是地址为NULL的内存,这当然是不对的。
友情提醒:记得free()
molloc申请的内存是位于堆中的,不用后要记得free()掉,否则会造成内存泄漏。
C99引入了变长数组,声明数组时方括号内可以用变量,但是变长数组声明时不能进行初始化。
数组名是一种地址常量
字符数组和字符指针变量的区别:
注意:
scanf("%s",&str[0]);
#include
#include
void RemoveDuplicate(char* s);
int main()
{
char str[200];
while(fgets(str, 200, stdin) != NULL)
{
RemoveDuplicate(str);
printf("%s", str);
}
return 0;
}
void RemoveDuplicate(char *s)
{
int r, w, i, len;//r为读头,w为写头!
len = strlen(s)+1;
for (r = w = 0; r < len; r++)
{
if(s[r] != '\0')
{
s[w] = s[r];
for (i = r + 1; i < len; i++)
{
if(s[i] == s[w])
s[i] = '\0';
}
w++;
}
}
s[w] = '\0';
}
int i;
char* str1[5], str2[5][80];//此处的str1是一个字符型指针数组!
for(i = 0; i<5; i++) str1[i] = str2[i];
for(i = 0; i<5; i++) scanf("%s",str1[i]);
#include
#include
#include
static int m, i, k, j, a;
int main()
{
int *nums;
nums = (int *)calloc(1000000,sizeof(int));
scanf("%d", &m);
for (nums[0] = 0, nums[1] = 0, i = 2; i < m; i++)
{
nums[i] = 1;//此处的i是需要测试的数,而其特征值为1表示为其为素数。
}
for (j = 2; j < sqrt(m); j++)
{
if (nums[j])
{
for (k = j * j; k < m; k += j)
{
nums[k] = 0;
}
}
}
for (a = 2; a < m; a++)
{
if (nums[a] && nums[a + 2])
{
printf("(%d,%d) ", a, a + 2);
}
}
return 0;
}
//虽然hdata的指针类型被改为char*,
//但是其指向的值的类型仍然是short类型
#define BYTEO(hdata) (*(char*)&hdata)
#define BYTEI(hdata) (*((char*)&hdata + 1))
short x = 10, y = 100;
printf("%hd\n", BYTEO(x));//不可用%c的转换说明!
printf("%hd\n", BYTEI(y));
char* p1 = "hanbo";
p1[0] = 'a';//这样修改会引发错误,因为后面所/
//有的相同字符串也会被修改。
printf("hanbo");//此时输出的就可能会用冲突。
char* s[80];
s[j] = (char*)malloc(strlen(t)+1);
int *pf(float(*a)(int))
//pf是一个函数,返回值为int *指针,参数为一个函数指针
int (*pf(char *))[5]
//pf是一个函数,该函数返回值为指向有5个int元素的数组的指针,参数为char *指针
double (*p[9])(int)
//p是9个元素的指针数组,数组中每个元素是指向有一个整型参数、返回值为双精度浮点型数的函数的指针
char *(*p[3])()
//p是3个元素的函数指针数组,函数指针数组中每个元素所指向的函数是无参字符指针函数
void readFloats(const char *fileName){
FILE *fp;
fp = fopen(fileName,"rb");
float nums[10];
for(int i = 0; i < 10; i++){
//注意指这一步操作!
unsigned bin = *(unsigned *)(nums + i);
for(int j = 31; j >=0; j--){
putchar('0'+ ( (bin>>j) &1));
}
putchar('\n');
}
fclose(fp);
}
struct stuff{
char job[20];
int age;
float height;
};
//直接带变量名Huqinwei
struct stuff{
char job[20];
int age;
float height;
}Huqinwei;
struct stuff Huqinwei = {"manager",30,185};
1 0 0 0 0 0 0 0 0 0
1 0 1 1 0 1 1 1 1 0
1 1 1 0 0 1 1 0 1 0
1 0 0 1 1 1 0 0 1 0
1 1 1 1 0 1 1 1 1 0
0 0 0 0 0 0 0 0 1 1
#include
#define N 1000
int mg[N][N], lj[N][N];
int n, m;
void fi(int x, int y);
int main()
{
int i, j;
//n行m列的迷宫
scanf("%d %d", &n, &m);
for (i = 0; i < n; i++)
for (j = 0; j < m; j++)
{
scanf("%d", &mg[i][j]);
lj[i][j] = 0;
}
//lj存储输出的路径
lj[0][0] = 1;
int x = 0, y = 0;
//递归求解迷宫问题
fi(x, y);
return 0;
}
void fi(int x, int y)
{
if (x == n - 1 && y == m - 1)
{
int i, j;
for (i = 0; i < n; i++)
for (j = 0; j < m; j++)
{
printf("%d", lj[i][j]);
if (j < m - 1) printf(" ");
else printf("\n");
}
}
else
{
int a, b, i;
for (i = 1; i < 5; i++)
{
switch (i)
{
case 1:a = x - 1;
b = y + 0;
break;
case 2:a = x + 1;
b = y + 0;
break;
case 3:a = x + 0;
b = y - 1;
break;
case 4:a = x + 0;
b = y + 1;
break;
}
if (mg[a][b] == 1 && lj[a][b] == 0)
{
lj[a][b] = 1;
mg[a][b] = 0;
fi(a, b);
lj[a][b] = 0;
mg[a][b] = 1;
}
}
}
}
ch=fgetc(fp);
while(!feof(fp)){
printf("%c ASCII: %d\n",ch,ch);
ch=fgetc(fp);
}