计算机存储正数和复数的原理
- 计算机存储正数的原理
- 正数的补码是该数的二进制形式
- 负数的补码要经过以下几个步骤获得
- 先取得该数的绝对值的二进制形式
- 再将第一步的值按位取反
- 最后将第二部的值加1
C语言和C的区别:
C语言是面向过程和语言:面向过程——分析出解决问题的步骤;然后把这些步骤一个一个的实现,使用时一个一个的调用C是面向对象的语言
- printf——f代表format格式:格式化输出语句
转义字符 | 意义 | ASCII码值(十进制) |
---|---|---|
\a | 响铃(BEL) | 007 |
\b | 退格(BS) ,将当前位置移到前一列 | 008 |
\f | 换页(FF),将当前位置移到下页开头 | 012 |
\n | 换行(LF) ,将当前位置移到下一行开头 | 010 |
\r | 回车(CR) ,将当前位置移到本行开头 | 013 |
\t | 水平制表(HT) (相当于tab键) | 009 |
\v | 垂直制表(VT) | 011 |
’ | 单引号 | 039 |
" | 双引号 | 034 |
\ | 反斜杠 | 092 |
\0 | 表示空 | 000 |
\ddd | 1~3位八进制表示的字符 | |
\xhh | 1~2位十六进制表示的字符 |
- sacnf(“”,&d,&g);
- scanf():冒号里面的一定要输入
const(不变的):修饰符,加在int前面,使该变量不可改变
变量
变量一般形式:<类型名称><变量名称>;
- 变量名只能是英文字母、数字或者下划线组成。
- 变量名的第一个字母不能是数字
- 变量名区分大小写
- 不能用关键字
变量类型 | scanf() | printf() | 有效数字位 |
---|---|---|---|
int | scanf(“%d”,···); | printf(“%d”,···); | 4 Byte |
float | scanf (“%f”,···); | printf(“%f”,···); | 4 Byte |
double | scanf (“%lf”,···); | printf(“%f”,···); | 8 Byte |
long double | scanf("%lf", ···); | printf("%f", ···); | 12 Byte |
char | scanf("%s", ···); | printf("%s",···); | 1 Byte |
char *pa = &a | scanf("%c", ···); | printf("%p",···); | 4 Byte |
数据类型
字符串
- char 变量名[number]:表示此变量有number个长度和字节
- 变量名[索引号] = 字符:对定义的变量进行赋值
eg.char name[5] = {‘F’,’i’,’s’,’h’,’c}
- 定义符号常量:
格式:#define 标识符 常量
解释:“define”函数将程序中出现的所有”标识符“替换为后面的”常量“
逻辑运算符
运算符 | 优先级 |
---|---|
&&(与) | 中 |
||(或) | 低 |
!(非) | 高 |
条件运算符
count = (count > 20) ? count – 10 : count + 10;
分支语句
if语句
if (表达式){
··· // 逻辑值为真时执行的语块
}else{
··· // 逻辑值为假时执行的语块
}
switch语句
- 一般与break混合使用
switch (表达式) {
case 常量表达式1:语句或程序块1;break;
case 常量表达式2:语句或程序块2;break;
···
case 常量表达式n:语句或程序块n;break;
default : 语句或程序块n+1;break;
}
循环语句
while语句
while (表达式){
循环体;
}
do···while()语句
do{
循环体
}while(表达式);
for语句
for (表达式1;表达式2;表达式3){ // 表达式1是循环初始化表达式;
循环体; // 表达式2是循环条件表达式
} // 表达式3是循环调整表达式
- break:跳出循环
- continue:跳过本轮循环
数组
数组的定义
类型 数组名 [ 元素个数 ]
访问数组中的元素
数组名 [ 下标 ]
- 注意:数组的最后一个元素一定是’\0’
// 输入10个数求平均数
#include <stdio.h>
#define NUM 10 // 定义一个数组常量,修改比较方便
int main(int argc, char const *argv[])
{
int s[NUM]; // 定义数组
int i, sum = 0;
printf("Please enter the number: ");
for (i = 0; i < NUM; i++){
scanf("%d", &s[i]);
printf("%d ", s[i]);
sum += s[i];
}
printf("\nThe average is : %.2f", (double)sum / NUM); // (double)强制改变数据类型
return 0;
}
// 动态数组的定义
#include <stdio.h>
int main(int argc, char const *argv[])
{
int x, i;
printf("Please enter the array size : ");
scanf("%d", &x);
int array[x]; // 此时的x就是刚刚用户输入的number
for (i = 0; i < x; i++){
printf("Please enter the elements of the array : ");
scanf("%d", &array[i]);
printf("array[%d] = %d\n", i, array[i]);
}
return 0;
}
// 动态数组储存字符串
#include <stdio.h>
int main(int argc, char const *argv[])
{
int x, i;
printf("Please enter the array size : ");
scanf("%d", &x);
char array[x+1];
printf("Please enter the elements of the array : ");
getchar();
for (i = 0; i < x; i++){
scanf("%c", &array[i]);
}
array[x] = '\n';
printf("array[%d] = %s\n", x, array);
return 0;
}
字符串处理函数
参数 | 含义 | printf( ) |
---|---|---|
strlen( ) | 获取字符串的长度,与sizeof( )比较,不计算字符串最后面的’\n’ | printf("%u"); |
sizeof( ) | 获取字符串的尺寸,与strlen( )比较,计算字符串最后面的’\n’ | printf("%d"); |
strcpy(str1, str2 ) | 将字符串str2拷贝到str1,str1一定要比str2大 | printf("%s"); |
strncpy( str1, str2, number) | 将字符串str2前面的number个元素拷贝到str1,str1一定要比str2大 | printf("%s"); |
strcat( str1, str2) | 拼接字符串str1和str2 | printf("%s"); |
strncat(str1,str2, number) | 将字符串str1和str2的前number个字符拼接 | printf("%s"); |
strcmp( ) | 比较字符串是否完全一致,完全一致返回0 | printf("%s"); |
strncmp( ) | 比较字符串前面的number个字符是否完全一致,完全一致返回0 | printf("%s"); |
strcpy()实例
#include <stdio.h>
#include <string.h> // 字符串函数库
int main(int argc, char const *argv[])
{
char str1[] = "Original String";
char str2[] = "New String";
char str3[100];
strcpy(str1, str2);
strcpy(str3, "Copy Successful"); // 将后面的数组复制到前面的数组里面
printf("str1 = %s\n", str1);
printf("str2 = %s\n", str2);
printf("str3 = %s\n", str3);
return 0;
}
strncpy()实例
#include <stdio.h>
#include <string.h> // 字符串函数库
int main(int argc, char const *argv[])
{
char str1[] = "Original String";
char str2[40];
strncpy(str2, str1, 8); // strncpy():将数组str1的前8个元素拷贝到str2里面,【注意:str2一定要比str1大】
str2[8] = '\0'; // 拷贝了前面8个元素,但是'\0'没有拷贝上,所以要加上去,不加上会读取到莫名其妙的东西
printf("str2 = %s\n", str2);
return 0;
}
strcat()实例
#include <stdio.h>
#include <string.h> // 字符串函数库
int main(int argc, char const *argv[])
{
char str1[] = "YanShun love";
char str2[] = "LiPing Very!";
strcat(str1, " "); // strcat():拼接字符串,将字符串str1后面接上空格,也就是'\0'的位置
strcat(str1, str2); // 再将str1和str2拼接
printf("str1 = %s\n", str1);
printf("str2 = %s\n", str2);
return 0;
}
strncat()实例
#include <stdio.h>
#include <string.h> // 字符串函数库
int main(int argc, char const *argv[])
{
char str1[] = "YanShun likes";
char str2[] = "LiPing VeryMuch!";
strcat(str1, " "); // strcat():拼接字符串,将字符串str1后面接上空格,也就是'\0'的位置
strncat(str1, str2, 6); // strncat():将字符串str1和str2的前6个字符拼接
printf("str1 = %s\n", str1);
printf("str2 = %s\n", str2);
return 0;
}
strcmp()实例
#include <stdio.h>
#include <string.h> // 字符串函数库
int main(int argc, char const *argv[])
{
char str1[] = "YanShun likes LiPing VeryMuch!";
char str2[] = "YanShun likes liping verymuch!";
char str3[40];
strcpy(str3, str1);
if (strcmp(str1, str3) == 0){ // 两个字符串完全一样,返回0,否则返回1
printf("str1 == str3\n");
}else{
printf("str1 != str3\n");
}
if (strcmp(str1, str2) == 0){
printf("str1 == str2\n");
}else{
printf("str1 != str2\n");
}
return 0;
}
二维数组
二维数组的定义
类型 数组名[ 常量表达式 ] [ 常量表达式 ]
二维数组的访问
数组名 [ 下标 ][ 下标 ]
- 要注意数组的下标范围,以防止越界访问
#include <stdio.h>
int main(int argc, char const *argv[])
{
int a[3][5] = {
{80, 92, 89, 90, 95},
{86, 78, 98, 90, 96},
{98, 97, 67, 72, 82}
};
int i, j;
for (i = 0; i < 5; i++){
for (j = 0; j < 3; j++){
// printf("a[%d][%d] = %d ", i, j, a[i][j]);
// printf("%-2d ", a[i][j]);
printf("%-2d ", a[j][i]);
}
printf("\n");
}
return 0;
}
指针
- 指针的本质在计算机里面就是一个地址
定义指针变量
类型名 *指针变量名
eg.
char *pa; // 定义一个指向字符型的指针变量
int *pb; // 定义一个指向整型的指针变量
取地址运算符和取值运算符
- 如果要获取某个变量的地址,可以使用取地址运算符(&)
char *pa = &a;
int *pb = &f;
- 如果需要访问指针变量指向的数据和数据类型,可以使用取值运算符(*)
printf("%c, %d\n", *pa, *pb);
#include <stdio.h>
int main(int argc, char const *argv[])
{
char a = 'F';
int f = 123;
// &取址运算符
// *取值运算符
char *pa = &a; // *pa = &a:pa取出地址a对应的值
int *pb = &f;
printf("a = %c\n", *pa);
printf("f = %d\n", *pb);
*pa = 'C';
*pb += 1;
printf("now a = %c\n", *pa); // 加上*打印的是地址指向的那个值
printf("now f = %d\n", *pb);
printf("*pa = %d\n", sizeof(pa));
printf("*pb = %d\n", sizeof(pb));
printf("a = %p\n", pa); // 未加上*打印的是地址
printf("f = %p\n", pb); // %p表示打印地址类型的数据
return 0;
}
- 数组名其实是数组的第一个元素的地址
- 数组里面的其余元素的地址就是前一个元素地址加上该数组对应类型的字节
#include <stdio.h>
int main(int argc, char const *argv[])
{
char str[128];
printf("Please enter what you want to say : ");
scanf("%s", str);
// printf("You want to say : %s\n", str);
printf("STR's address is : %p\n", str);
printf("STR's address the first one is : %p\n", &str[0]);// &取址操作符
// 由以上两个printf可得出结论:数组名其实是数组的第一个元素的地址
return 0;
}
// 数组里面的其余元素的地址就是前一个元素地址加上该数组对应类型的字节
#include <stdio.h>
int main(int argc, char const *argv[])
{
char a[] = "yanshun";
int b[5] = {1, 2, 3, 4, 5};
float c[5] = {1.1, 2.2, 3.3, 4.4, 5.5};
double d[5] = {1.1, 2.2, 3.3, 4.4, 5.5};
printf(" a[0] = %p\n a[1] = %p\n a[2] = %p\n a[3] = %p\n a[4] = %p\n", &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]);
printf("\n b[0] = %p\n b[1] = %p\n b[2] = %p\n b[3] = %p\n b[4] = %p\n", &b[0], &b[1], &b[2], &b[3], &b[4], &a[5]);
printf("\n c[0] = %p\n c[1] = %p\n c[2] = %p\n c[3] = %p\n c[4] = %p\n", &c[0], &c[1], &c[2], &c[3], &c[4], &a[5]);
printf("\n d[0] = %p\n d[1] = %p\n d[2] = %p\n d[3] = %p\n d[4] = %p\n", &d[0], &d[1], &d[2], &d[3], &d[4], &a[5]);
return 0;
}
指针的运算
- 当指针指向数组元素的时候,我们可以对指针变量进行加减运算,这样做的意义相当于指向距离指针所在位置向前或向后第n个元素
#include <stdio.h>
int main(int argc, char const *argv[])
{
char a[] = "yan";
char *p = a;
printf(" *p = %c\n *(p+1) = %c\n *(p+2) = %c\n", *p, *(p+1), *(p+2));
return 0;
}
- 指针指向数组的第n个元素并不是加减数组对应的类型的字符数,而是加减1
#include <stdio.h>
int main(int argc, char const *argv[])
{
char a[] = "yanshun";
int b[5] = {1, 2, 3, 4, 5};
float c[5] = {1.1, 2.2, 3.3, 4.4, 5.5};
double d[5] = {1.1, 2.2, 3.3, 4.4, 5.5};
printf(" a[0] = %c\n a[1] = %c\n a[2] = %c\n", *a, *(a+1), *(a+2));
printf("\n b[0] = %d\n b[1] = %d\n b[2] = %d\n b[3] = %d\n b[4] = %d\n", *b, *(b+1), *(b+2), *(b+3), *(b+4));
printf("\n c[0] = %.1f\n c[1] = %.1f\n c[2] = %.1f\n c[3] = %.1f\n c[4] = %.1f\n", *c, *(c+1), *(c+2), *(c+3), *(c+4));
printf("\n d[0] = %.1lf\n d[1] = %.1lf\n d[2] = %.1lf\n d[3] = %.1lf\n d[4] = %.1lf\n", *d, *(d+1), *(d+2), *(d+3), *(d+4));
return 0;
}
#include <stdio.h>
#include <string.h> // 字符串函数库
int main(int argc, char const *argv[])
{
char *str = "yanshun like liping"; // 直接定义一个指针变量
int i, length;
length = strlen(str); // strlen():获取字符串的长度
for (i = 0; i < length; i++){
printf("str[%d] = %c\n", i, str[i]);
}
return 0;
}
指针和数组
// 数组名是一个地址,而指针是一个左值
#include <stdio.h>
int main(int argc, char const *argv[])
{
char str[] = "yanshun like liping very much!"; // 数组名是一个常量,不可改
char *target = str; // 这里要用一个指针(*target),指向字符串,指针是一个左值(lvalue),可改
int count = 0;
while(*target++ != '\0'){
count++;
}
printf("count = %d\n", count);
return 0;
}
指针数组和数组指针
- 指针数组是一个数组,它指向的是一个指针
int *p1[5];
#include <stdio.h>
int main(int argc, char const *argv[])
{
int a = 1, b = 2, c = 3, d = 4, e = 5;
int *pl[5] = {&a, &b, &c, &d, &e}; // &地址运算符
int i;
for (i = 0; i < 5; i++){
printf("%d\n", *pl[i]); // []优先级高于*取址运算符
}
return 0;
}
- 数组指针是一个指针,它指向的是一个数组
int (*p2)[5];
#include <stdio.h>
int main(int argc, char const *argv[])
{
int temp[5] = {1, 2, 3, 4, 5};
int (*p2)[5] = &temp; // 数组指针指向的是一个数组(&temp)
// int (*p2)[5] = temp; // 这样写指向的是数组里面的第一个元素的地址
int i;
for (i = 0; i < 5; i++){
printf("%d\n", *(*p2+i));
}
return 0;
}